Skip to content

Commit 2c8acfc

Browse files
authored
Fix getEffectiveRegistry to return registry only (#569)
2 parents aa9834d + 834074e commit 2c8acfc

4 files changed

Lines changed: 84 additions & 16 deletions

File tree

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,14 @@ public static ContainerRef parse(String name) {
401401
*/
402402
public String getEffectiveRegistry(Registry target) {
403403
if (isUnqualified()) {
404-
String key = getAliasKey();
404+
String key = target.getRegistriesConf().getAliasKey(this);
405405
if (target.getRegistry() == null && target.getRegistriesConf().hasAlias(key)) {
406-
return target.getRegistriesConf().getAliases().get(key);
406+
// Extract everything before the first slash (if any) as the registry for alias lookup, otherwise use
407+
// the repository as the key
408+
String value = target.getRegistriesConf().getAliases().get(key);
409+
String domain = value.split("/")[0];
410+
LOG.debug("Effective registry for alias {} is {}", key, domain);
411+
return domain;
407412
}
408413
return target.getRegistry() != null
409414
? target.getRegistry()
@@ -489,7 +494,7 @@ public String getTarget(OCI<ContainerRef> target) {
489494
*/
490495
public ContainerRef forRegistry(Registry registry) {
491496
if (isUnqualified() && registry.getRegistry() == null) {
492-
String key = getAliasKey();
497+
String key = registry.getRegistriesConf().getAliasKey(this);
493498
if (registry.getRegistry() == null && registry.getRegistriesConf().hasAlias(key)) {
494499
String newLocation = registry.getRegistriesConf().getAliases().get(key);
495500
String newRefString = "%s:%s".formatted(newLocation, tag);
@@ -514,15 +519,6 @@ public ContainerRef forRegistry(Registry registry) {
514519
digest);
515520
}
516521

517-
/**
518-
* Return the key of the alias
519-
*/
520-
private String getAliasKey() {
521-
return getRegistry().equals(Const.DEFAULT_REGISTRY) && "library".equals(getNamespace())
522-
? getRepository()
523-
: getFullRepository();
524-
}
525-
526522
private String determineFirstUnqualifiedSearchRegistry(Registry registry) {
527523
// No settings, keep old behavior of defaulting to docker.io for unqualified reference
528524
if (registry.getRegistriesConf().getUnqualifiedRegistries().isEmpty()) {

src/main/java/land/oras/auth/RegistriesConf.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Optional;
3636
import land.oras.ContainerRef;
3737
import land.oras.exception.OrasException;
38+
import land.oras.utils.Const;
3839
import land.oras.utils.TomlUtils;
3940
import org.jspecify.annotations.NullMarked;
4041
import org.jspecify.annotations.Nullable;
@@ -192,6 +193,17 @@ public List<String> getUnqualifiedRegistries() {
192193
return Collections.unmodifiableList(config.unqualifiedRegistries);
193194
}
194195

196+
/**
197+
* Return the key of the alias
198+
* @param ref the container reference to get the alias key for.
199+
* @return the alias key for the given container reference, which is either the repository name
200+
*/
201+
public String getAliasKey(ContainerRef ref) {
202+
return ref.getRegistry().equals(Const.DEFAULT_REGISTRY) && "library".equals(ref.getNamespace())
203+
? ref.getRepository()
204+
: ref.getFullRepository();
205+
}
206+
195207
/**
196208
* Enforce the short name mode by checking the configuration. If the short name mode is set to ENFORCING or PERMISSIVE and there are multiple unqualified registries configured, this method throws an OrasException indicating that the configuration is invalid. If the configuration is valid, this method does nothing.
197209
* @throws OrasException if the short name mode is set to ENFORCING or PERMISSIVE and there are multiple unqualified registries configured, indicating that the configuration is invalid.
@@ -250,6 +262,7 @@ public boolean isInsecure(ContainerRef location) {
250262
* @return the rewritten container reference.
251263
*/
252264
public ContainerRef rewrite(ContainerRef ref) {
265+
253266
Optional<RegistryConfig> matchingConfig = selectMatchingTable(ref);
254267
if (matchingConfig.isEmpty()) {
255268
return ref;

src/test/java/land/oras/ContainerRefTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,18 @@ void shouldDetermineFromAlias(@TempDir Path homeDir) throws Exception {
8585
String config =
8686
"""
8787
[aliases]
88-
"my-library/my-namespace"="localhost/test"
89-
"my-library"="localhost/test2"
88+
"my-library/my-namespace"="localhost:5000/test"
89+
"my-library"="localhost:5000/test2"
9090
""";
9191

9292
TestUtils.createRegistriesConfFile(homeDir, config);
9393

9494
TestUtils.withHome(homeDir, () -> {
9595
Registry registry = Registry.builder().defaults().build();
9696
ContainerRef unqualifiedRef = ContainerRef.parse("my-library/my-namespace");
97-
assertEquals("localhost/test", unqualifiedRef.getEffectiveRegistry(registry));
97+
assertEquals("localhost:5000", unqualifiedRef.getEffectiveRegistry(registry));
9898
ContainerRef unqualifiedRef2 = ContainerRef.parse("my-library");
99-
assertEquals("localhost/test2", unqualifiedRef2.getEffectiveRegistry(registry));
99+
assertEquals("localhost:5000", unqualifiedRef2.getEffectiveRegistry(registry));
100100
});
101101
}
102102

src/test/java/land/oras/RegistryTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import land.oras.utils.ZotUnsecureContainer;
4141
import org.junit.jupiter.api.Assertions;
4242
import org.junit.jupiter.api.BeforeEach;
43+
import org.junit.jupiter.api.Disabled;
4344
import org.junit.jupiter.api.Test;
4445
import org.junit.jupiter.api.io.TempDir;
4546
import org.junit.jupiter.api.parallel.Execution;
@@ -862,6 +863,64 @@ void testShouldCopySingleArtifactFromRegistryIntoRegistry() throws IOException {
862863
}
863864
}
864865

866+
@Test
867+
@Execution(ExecutionMode.SAME_THREAD)
868+
@Disabled("#")
869+
void testShouldCopyFromAliasToAlias(@TempDir Path homeDir) throws Exception {
870+
871+
try (RegistryContainer otherRegistryContainer = new RegistryContainer()) {
872+
873+
otherRegistryContainer.start();
874+
875+
// language=toml
876+
String config =
877+
"""
878+
[aliases]
879+
"the-source" = "%s/test/artifact-source"
880+
"the-target" = "%s/test/artifact-target"
881+
882+
[[registry]]
883+
location = "%s"
884+
insecure = true
885+
886+
[[registry]]
887+
location = "%s"
888+
insecure = true
889+
"""
890+
.formatted(
891+
this.registry.getRegistry(),
892+
otherRegistryContainer.getRegistry(),
893+
this.registry.getRegistry(),
894+
otherRegistryContainer.getRegistry());
895+
TestUtils.createRegistriesConfFile(homeDir, config);
896+
897+
// Copy to same registry
898+
TestUtils.withHome(homeDir, () -> {
899+
try {
900+
Registry registry = Registry.Builder.builder()
901+
.defaults("myuser", "mypass")
902+
.build();
903+
904+
ContainerRef containerSource = ContainerRef.parse("the-source");
905+
Path file1 = blobDir.resolve("source.txt");
906+
Files.writeString(file1, "foobar");
907+
908+
// Push
909+
Manifest manifest = registry.pushArtifact(containerSource, LocalPath.of(file1));
910+
assertNotNull(manifest);
911+
912+
// Copy to other registry
913+
ContainerRef containerTarget = ContainerRef.parse("the-target");
914+
CopyUtils.copy(registry, containerSource, registry, containerTarget, false);
915+
registry.pullArtifact(containerTarget, artifactDir, true);
916+
assertEquals("foobar", Files.readString(artifactDir.resolve("source.txt")));
917+
} catch (Exception e) {
918+
throw new RuntimeException(e);
919+
}
920+
});
921+
}
922+
}
923+
865924
@Test
866925
void testShouldCopyFromOciLayoutToRegistryNonRecursive() throws IOException {
867926

0 commit comments

Comments
 (0)