Skip to content

Commit 31c7530

Browse files
committed
Allow use of org_path with mirrored images
Fixes the logic when adding mirrors with an optional org_path.
1 parent 54dbe33 commit 31c7530

File tree

2 files changed

+113
-40
lines changed

2 files changed

+113
-40
lines changed

pkg/registries/registries.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,17 @@ func extractRegistryHostname(fullImage string) string {
101101
return strings.Split(fullImage, imagePathSeparator)[0]
102102
}
103103

104+
// extractRegistryOrgPath returns only the org path when given a reference to a registry.
105+
// The input for this function should not include an image name.
106+
func extractRegistryOrgPath(registry string) string {
107+
hostname := extractRegistryHostname(registry)
108+
hostnameSplit := strings.SplitN(registry, hostname, 2)
109+
if len(hostnameSplit) != 2 {
110+
return ""
111+
}
112+
return strings.TrimPrefix(hostnameSplit[1], "/")
113+
}
114+
104115
// getMergedMirrorSets extracts and merges the contents of the given mirror sets.
105116
// The resulting slice of mirrorSets represents a system-wide image registry configuration.
106117
func getMergedMirrorSets(idmsItems []config.ImageDigestMirrorSet, idtsItems []config.ImageTagMirrorSet) []mirrorSet {
@@ -218,14 +229,24 @@ func (ms *mirrorSet) generateConfig(secretsConfig credentialprovider.DockerConfi
218229
// set the fallback server to the first mirror to ensure the source is never contacted, even if all mirrors fail
219230
fallbackServer = ms.mirrors[0].host
220231
}
221-
result += fmt.Sprintf("server = \"https://%s\"", fallbackServer)
222-
result += "\n"
232+
fallbackRegistry := extractRegistryHostname(fallbackServer)
233+
result += fmt.Sprintf("server = \"https://%s/v2", fallbackRegistry)
234+
if orgPath := extractRegistryOrgPath(fallbackServer); orgPath != "" {
235+
result += "/" + orgPath
236+
}
237+
result += "\"\n"
238+
result += "\noverride_path = true\n"
223239

224240
// Each mirror should result in an entry followed by a set of settings for interacting with the mirror host
225241
for _, m := range ms.mirrors {
242+
hostRegistry := extractRegistryHostname(m.host)
243+
hostOrgPath := extractRegistryOrgPath(m.host)
226244
result += "\n"
227-
result += fmt.Sprintf("[host.\"https://%s\"]", m.host)
228-
result += "\n"
245+
result += fmt.Sprintf("[host.\"https://%s/v2", hostRegistry)
246+
if hostOrgPath != "" {
247+
result += "/" + hostOrgPath
248+
}
249+
result += "\"]\n"
229250

230251
// Specify the operations the registry host may perform. IDMS mirrors can only be pulled by directly by digest,
231252
// whereas ITMS mirrors have the additional resolve capability, which allows converting a tag name into a digest
@@ -237,15 +258,19 @@ func (ms *mirrorSet) generateConfig(secretsConfig credentialprovider.DockerConfi
237258
}
238259
result += hostCapabilities
239260
result += "\n"
261+
result += " override_path = true\n"
240262

241263
// Extract the mirror repo's authorization credentials, if one exists
242264
if entry, ok := secretsConfig.Auths[extractRegistryHostname(m.host)]; ok {
243265
credentials := entry.Username + ":" + entry.Password
244266
token := base64.StdEncoding.EncodeToString([]byte(credentials))
245267

246268
// Add the access token as a request header
247-
result += fmt.Sprintf(" [host.\"https://%s\".header]", m.host)
248-
result += "\n"
269+
result += fmt.Sprintf(" [host.\"https://%s/v2", hostRegistry)
270+
if hostOrgPath != "" {
271+
result += "/" + hostOrgPath
272+
}
273+
result += "\".header]\n"
249274
result += fmt.Sprintf(" authorization = \"Basic %s\"", token)
250275
result += "\n"
251276
}

pkg/registries/registries_test.go

Lines changed: 82 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func TestGenerateConfig(t *testing.T) {
237237
{
238238
name: "empty mirrors",
239239
input: mirrorSet{
240-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
240+
source: "registry.access.redhat.com/ubi9",
241241
mirrors: []mirror{},
242242
mirrorSourcePolicy: config.AllowContactingSource,
243243
},
@@ -246,114 +246,136 @@ func TestGenerateConfig(t *testing.T) {
246246
{
247247
name: "basic one digest mirror",
248248
input: mirrorSet{
249-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
249+
source: "registry.access.redhat.com",
250250
mirrors: []mirror{
251-
{host: "example.io/example/ubi-minimal", resolveTags: false},
251+
{host: "example.io/example", resolveTags: false},
252252
},
253253
mirrorSourcePolicy: config.AllowContactingSource,
254254
},
255-
expectedOutput: `server = "https://registry.access.redhat.com/ubi9/ubi-minimal"
255+
expectedOutput: `server = "https://registry.access.redhat.com/v2"
256256
257-
[host."https://example.io/example/ubi-minimal"]
257+
override_path = true
258+
259+
[host."https://example.io/v2/example"]
258260
capabilities = ["pull"]
261+
override_path = true
259262
`,
260263
},
261264
{
262265
name: "basic one tag mirror",
263266
input: mirrorSet{
264-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
267+
source: "registry.access.redhat.com",
265268
mirrors: []mirror{
266-
{host: "example.io/example/ubi-minimal", resolveTags: true},
269+
{host: "example.io/example", resolveTags: true},
267270
},
268271
mirrorSourcePolicy: config.AllowContactingSource,
269272
},
270-
expectedOutput: `server = "https://registry.access.redhat.com/ubi9/ubi-minimal"
273+
expectedOutput: `server = "https://registry.access.redhat.com/v2"
274+
275+
override_path = true
271276
272-
[host."https://example.io/example/ubi-minimal"]
277+
[host."https://example.io/v2/example"]
273278
capabilities = ["pull", "resolve"]
279+
override_path = true
274280
`,
275281
},
276282
{
277283
name: "one digest mirror never contact source",
278284
input: mirrorSet{
279-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
285+
source: "registry.access.redhat.com",
280286
mirrors: []mirror{
281-
{host: "example.io/example/ubi-minimal", resolveTags: false},
287+
{host: "example.io/example", resolveTags: false},
282288
},
283289
mirrorSourcePolicy: config.NeverContactSource,
284290
},
285-
expectedOutput: `server = "https://example.io/example/ubi-minimal"
291+
expectedOutput: `server = "https://example.io/v2/example"
292+
293+
override_path = true
286294
287-
[host."https://example.io/example/ubi-minimal"]
295+
[host."https://example.io/v2/example"]
288296
capabilities = ["pull"]
297+
override_path = true
289298
`,
290299
},
291300
{
292301
name: "tags mirror never contact source",
293302
input: mirrorSet{
294-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
303+
source: "registry.access.redhat.com",
295304
mirrors: []mirror{
296-
{host: "example.io/example/ubi-minimal", resolveTags: true},
305+
{host: "example.io/example", resolveTags: true},
297306
},
298307
mirrorSourcePolicy: config.NeverContactSource,
299308
},
300-
expectedOutput: `server = "https://example.io/example/ubi-minimal"
309+
expectedOutput: `server = "https://example.io/v2/example"
301310
302-
[host."https://example.io/example/ubi-minimal"]
311+
override_path = true
312+
313+
[host."https://example.io/v2/example"]
303314
capabilities = ["pull", "resolve"]
315+
override_path = true
304316
`,
305317
},
306318
{
307319
name: "multiple mirrors",
308320
input: mirrorSet{
309-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
321+
source: "registry.access.redhat.com",
310322
mirrors: []mirror{
311-
{host: "example.io/example/ubi-minimal", resolveTags: false},
323+
{host: "example.io/example", resolveTags: false},
312324
{host: "mirror.example.com/redhat", resolveTags: false},
313-
{host: "mirror.example.net/image", resolveTags: true},
325+
{host: "mirror.example.net", resolveTags: true},
314326
},
315327
mirrorSourcePolicy: config.AllowContactingSource,
316328
},
317-
expectedOutput: `server = "https://registry.access.redhat.com/ubi9/ubi-minimal"
329+
expectedOutput: `server = "https://registry.access.redhat.com/v2"
330+
331+
override_path = true
318332
319-
[host."https://example.io/example/ubi-minimal"]
333+
[host."https://example.io/v2/example"]
320334
capabilities = ["pull"]
335+
override_path = true
321336
322-
[host."https://mirror.example.com/redhat"]
337+
[host."https://mirror.example.com/v2/redhat"]
323338
capabilities = ["pull"]
324-
[host."https://mirror.example.com/redhat".header]
339+
override_path = true
340+
[host."https://mirror.example.com/v2/redhat".header]
325341
authorization = "Basic dXNlcjpwYXNz"
326342
327-
[host."https://mirror.example.net/image"]
343+
[host."https://mirror.example.net/v2"]
328344
capabilities = ["pull", "resolve"]
329-
[host."https://mirror.example.net/image".header]
345+
override_path = true
346+
[host."https://mirror.example.net/v2".header]
330347
authorization = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
331348
`,
332349
},
333350
{
334351
name: "multiple mirrors never contact source",
335352
input: mirrorSet{
336-
source: "registry.access.redhat.com/ubi9/ubi-minimal",
353+
source: "registry.access.redhat.com",
337354
mirrors: []mirror{
338-
{host: "example.io/example/ubi-minimal", resolveTags: false},
355+
{host: "example.io/example", resolveTags: false},
339356
{host: "mirror.example.com/redhat", resolveTags: false},
340357
{host: "mirror.example.net", resolveTags: true},
341358
},
342359
mirrorSourcePolicy: config.NeverContactSource,
343360
},
344-
expectedOutput: `server = "https://example.io/example/ubi-minimal"
361+
expectedOutput: `server = "https://example.io/v2/example"
345362
346-
[host."https://example.io/example/ubi-minimal"]
363+
override_path = true
364+
365+
[host."https://example.io/v2/example"]
347366
capabilities = ["pull"]
367+
override_path = true
348368
349-
[host."https://mirror.example.com/redhat"]
369+
[host."https://mirror.example.com/v2/redhat"]
350370
capabilities = ["pull"]
351-
[host."https://mirror.example.com/redhat".header]
371+
override_path = true
372+
[host."https://mirror.example.com/v2/redhat".header]
352373
authorization = "Basic dXNlcjpwYXNz"
353374
354-
[host."https://mirror.example.net"]
375+
[host."https://mirror.example.net/v2"]
355376
capabilities = ["pull", "resolve"]
356-
[host."https://mirror.example.net".header]
377+
override_path = true
378+
[host."https://mirror.example.net/v2".header]
357379
authorization = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
358380
`,
359381
},
@@ -681,3 +703,29 @@ func TestExtractMirrorURL(t *testing.T) {
681703
})
682704
}
683705
}
706+
707+
func TestExtractOrgPath(t *testing.T) {
708+
tests := []struct {
709+
input string
710+
expected string
711+
}{
712+
{
713+
input: "registry.local/org",
714+
expected: "org",
715+
},
716+
{
717+
input: "registry.local/org/sub_org",
718+
expected: "org/sub_org",
719+
},
720+
{
721+
input: "registry.local",
722+
expected: "",
723+
},
724+
}
725+
for _, tt := range tests {
726+
t.Run(tt.input, func(t *testing.T) {
727+
result := extractRegistryOrgPath(tt.input)
728+
assert.Equal(t, tt.expected, result)
729+
})
730+
}
731+
}

0 commit comments

Comments
 (0)