Skip to content

Commit db02434

Browse files
authored
fix: Prepend Docker Hub namespace to repository (#1287)
1 parent 0ad2b49 commit db02434

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

src/Testcontainers/Images/DockerImage.cs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public sealed class DockerImage : IImage
1515

1616
private static readonly char[] TrimChars = [' ', ':', '/'];
1717

18+
private static readonly char[] SlashChar = ['/'];
19+
1820
private static readonly Func<string, IImage> GetDockerImage = MatchImage.Match;
1921

2022
[NotNull]
@@ -27,10 +29,7 @@ public sealed class DockerImage : IImage
2729
private readonly string _tag;
2830

2931
[CanBeNull]
30-
private readonly string _digit;
31-
32-
[CanBeNull]
33-
private readonly string _hubImageNamePrefix;
32+
private readonly string _digest;
3433

3534
/// <summary>
3635
/// Initializes a new instance of the <see cref="DockerImage" /> class.
@@ -66,32 +65,63 @@ public DockerImage(
6665
string tag = null,
6766
string digest = null,
6867
string hubImageNamePrefix = null)
68+
: this(
69+
TrimOrDefault(repository),
70+
TrimOrDefault(registry),
71+
TrimOrDefault(tag, tag == null && digest == null ? LatestTag : null),
72+
TrimOrDefault(digest),
73+
hubImageNamePrefix == null ? [] : hubImageNamePrefix.Trim(TrimChars).Split(SlashChar, 2, StringSplitOptions.RemoveEmptyEntries))
74+
{
75+
}
76+
77+
private DockerImage(
78+
string repository,
79+
string registry,
80+
string tag,
81+
string digest,
82+
string[] substitutions)
6983
{
7084
_ = Guard.Argument(repository, nameof(repository))
7185
.NotNull()
7286
.NotEmpty()
7387
.NotUppercase();
7488

75-
var defaultTag = tag == null && digest == null ? LatestTag : null;
89+
_ = Guard.Argument(substitutions, nameof(substitutions))
90+
.NotNull();
91+
92+
// The Docker Hub image name prefix may include namespaces, which we need to extract
93+
// and prepend to the repository name. The registry itself contains only the hostname.
94+
switch (substitutions.Length)
95+
{
96+
case 2:
97+
_repository = string.Join("/", substitutions[1], repository);
98+
_registry = substitutions[0];
99+
break;
100+
case 1:
101+
_repository = repository;
102+
_registry = substitutions[0];
103+
break;
104+
default:
105+
_repository = repository;
106+
_registry = registry;
107+
break;
108+
}
76109

77-
_repository = TrimOrDefault(repository);
78-
_registry = TrimOrDefault(registry);
79-
_tag = TrimOrDefault(tag, defaultTag);
80-
_digit = TrimOrDefault(digest);
81-
_hubImageNamePrefix = TrimOrDefault(hubImageNamePrefix);
110+
_tag = tag;
111+
_digest = digest;
82112
}
83113

84114
/// <inheritdoc />
85115
public string Repository => _repository;
86116

87117
/// <inheritdoc />
88-
public string Registry => string.IsNullOrEmpty(_hubImageNamePrefix) ? _registry : _hubImageNamePrefix;
118+
public string Registry => _registry;
89119

90120
/// <inheritdoc />
91121
public string Tag => _tag;
92122

93123
/// <inheritdoc />
94-
public string Digest => _digit;
124+
public string Digest => _digest;
95125

96126
/// <inheritdoc />
97127
public string FullName

tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public sealed class DockerImageFixture : TheoryData<DockerImageFixtureSerializab
1616
private const string DotSeparatorRegistry = "myregistry.azurecr.io";
1717
private const string PortSeparatorRegistry = "myregistry:5000";
1818
private const string Digest = "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
19+
private const string HubImageNamePrefixImplicitLibrary = "myregistry.azurecr.io";
20+
private const string HubImageNamePrefixExplicitLibrary = "myregistry.azurecr.io/library";
1921

2022
public DockerImageFixture()
2123
{
@@ -35,6 +37,8 @@ public DockerImageFixture()
3537
Add(new DockerImageFixtureSerializable(new DockerImage(FedoraHttpd, PortSeparatorRegistry, CustomTag1, null)), $"{PortSeparatorRegistry}/{FedoraHttpd}:{CustomTag1}", $"{PortSeparatorRegistry}/{FedoraHttpd}:{CustomTag1}");
3638
Add(new DockerImageFixtureSerializable(new DockerImage(FooBarBaz, DotSeparatorRegistry, SemVerTag, Digest)), $"{DotSeparatorRegistry}/{FooBarBaz}:{SemVerTag}@{Digest}", $"{DotSeparatorRegistry}/{FooBarBaz}:{SemVerTag}@{Digest}");
3739
Add(new DockerImageFixtureSerializable(new DockerImage(FooBarBaz, DotSeparatorRegistry, null, Digest)), $"{DotSeparatorRegistry}/{FooBarBaz}@{Digest}", $"{DotSeparatorRegistry}/{FooBarBaz}@{Digest}");
40+
Add(new DockerImageFixtureSerializable(new DockerImage(FooBarBaz, null, null, null, HubImageNamePrefixImplicitLibrary)), $"{HubImageNamePrefixImplicitLibrary}/{FooBarBaz}", $"{HubImageNamePrefixImplicitLibrary}/{FooBarBaz}:{LatestTag}");
41+
Add(new DockerImageFixtureSerializable(new DockerImage(FooBarBaz, null, null, null, HubImageNamePrefixExplicitLibrary)), $"{HubImageNamePrefixExplicitLibrary}/{FooBarBaz}", $"{HubImageNamePrefixExplicitLibrary}/{FooBarBaz}:{LatestTag}");
3842
}
3943
}
4044
}

0 commit comments

Comments
 (0)