Skip to content

Commit a7ad6b3

Browse files
committed
Add support for registry host path override
Adds support for mirrors which are non-compliant with the OCI distribution specification but have previously mirrored content with a namespace prefix after the API root `/v2`. Signed-off-by: Derek McGowan <[email protected]>
1 parent 95c7085 commit a7ad6b3

3 files changed

Lines changed: 42 additions & 7 deletions

File tree

docs/hosts.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,17 @@ or
274274
x-custom-1-2 = "another custom header"
275275
```
276276

277+
## override_path field
278+
279+
`override_path` is used to indicate the host's API root endpoint is defined
280+
in the URL path rather than by the API specification. This may be used with
281+
non-compliant OCI registries which are missing the `/v2` prefix.
282+
(Defaults to `false`)
283+
284+
```
285+
override_path = true
286+
```
287+
277288
## host field(s) (in the toml table format)
278289

279290
`[host]."https://namespace"` and `[host].http://namespace` entries in the
@@ -310,6 +321,10 @@ for this registry host namespace:
310321
311322
[host."https://test-3.registry"]
312323
client = ["/etc/certs/client-1.pem", "/etc/certs/client-2.pem"]
324+
325+
[host."https://non-compliant-mirror.registry/v2/upstream"]
326+
capabilities = ["pull"]
327+
override_path = true
313328
```
314329

315330
**Note**: Recursion is not supported in the specification of host mirror

remotes/docker/config/hosts.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ type hostFileConfig struct {
291291
// Accepted types
292292
// - string - Single file with public and private keys
293293
// - []string - Multiple files with public and private keys
294-
// - [][2]string - Muliple keypairs with public and private keys in separate files
294+
// - [][2]string - Multiple keypairs with public and private keys in separate files
295295
Client interface{} `toml:"client"`
296296

297297
// SkipVerify skips verification of the server's certificate chain
@@ -302,6 +302,12 @@ type hostFileConfig struct {
302302
// Header are additional header files to send to the server
303303
Header map[string]interface{} `toml:"header"`
304304

305+
// OverridePath indicates the API root endpoint is defined in the URL
306+
// path rather than by the API specification.
307+
// This may be used with non-compliant OCI registries to override the
308+
// API root endpoint.
309+
OverridePath bool `toml:"override_path"`
310+
305311
// TODO: Credentials: helper? name? username? alternate domain? token?
306312
}
307313

@@ -374,16 +380,12 @@ func parseHostConfig(server string, baseDir string, config hostFileConfig) (host
374380
}
375381
result.scheme = u.Scheme
376382
result.host = u.Host
377-
// TODO: Handle path based on registry protocol
378-
// Define a registry protocol type
379-
// OCI v1 - Always use given path as is
380-
// Docker v2 - Always ensure ends with /v2/
381383
if len(u.Path) > 0 {
382384
u.Path = path.Clean(u.Path)
383-
if !strings.HasSuffix(u.Path, "/v2") {
385+
if !strings.HasSuffix(u.Path, "/v2") && !config.OverridePath {
384386
u.Path = u.Path + "/v2"
385387
}
386-
} else {
388+
} else if !config.OverridePath {
387389
u.Path = "/v2"
388390
}
389391
result.path = u.Path

remotes/docker/config/hosts_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ ca = "/etc/path/default"
104104
105105
[host."https://test-3.registry"]
106106
client = ["/etc/certs/client-1.pem", "/etc/certs/client-2.pem"]
107+
108+
[host."https://noncompliantmirror.registry/v2/namespaceprefix"]
109+
capabilities = ["pull"]
110+
override_path = true
111+
112+
[host."https://noprefixnoncompliant.registry"]
113+
override_path = true
107114
`
108115
var tb, fb = true, false
109116
expected := []hostConfig{
@@ -159,6 +166,17 @@ ca = "/etc/path/default"
159166
{filepath.FromSlash("/etc/certs/client-2.pem")},
160167
},
161168
},
169+
{
170+
scheme: "https",
171+
host: "noncompliantmirror.registry",
172+
path: "/v2/namespaceprefix",
173+
capabilities: docker.HostCapabilityPull,
174+
},
175+
{
176+
scheme: "https",
177+
host: "noprefixnoncompliant.registry",
178+
capabilities: allCaps,
179+
},
162180
{
163181
scheme: "https",
164182
host: "test-default.registry",

0 commit comments

Comments
 (0)