Skip to content

Commit aaaf978

Browse files
committed
Add custom capabilities setting to registry config
Allows a registry mirror to be configured with the "push" capability which can be helpful in some proxy use-cases. Signed-off-by: Will Jordan <will.jordan@gmail.com>
1 parent d5a40ad commit aaaf978

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

util/resolver/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type RegistryConfig struct {
77
RootCAs []string `toml:"ca"`
88
KeyPairs []TLSKeyPair `toml:"keypair"`
99
TLSConfigDir []string `toml:"tlsconfigdir"`
10+
Capabilities []string `toml:"capabilities"`
1011
}
1112

1213
type TLSKeyPair struct {

util/resolver/resolver.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ const (
2525
defaultPath = "/v2"
2626
)
2727

28+
func fillConfigOpts(host string, c config.RegistryConfig, h docker.RegistryHost) (*docker.RegistryHost, error) {
29+
if len(c.Capabilities) > 0 {
30+
h.Capabilities = 0
31+
for _, capability := range c.Capabilities {
32+
switch strings.ToLower(capability) {
33+
case "pull":
34+
h.Capabilities |= docker.HostCapabilityPull
35+
case "resolve":
36+
h.Capabilities |= docker.HostCapabilityResolve
37+
case "push":
38+
h.Capabilities |= docker.HostCapabilityPush
39+
default:
40+
return nil, errors.Errorf("unknown capability %v", c)
41+
}
42+
}
43+
}
44+
45+
return fillInsecureOpts(host, c, h)
46+
}
2847
func fillInsecureOpts(host string, c config.RegistryConfig, h docker.RegistryHost) (*docker.RegistryHost, error) {
2948
tc, err := loadTLSConfig(c)
3049
if err != nil {
@@ -134,7 +153,7 @@ func NewRegistryConfig(m map[string]config.RegistryConfig) docker.RegistryHosts
134153
for _, rawMirror := range c.Mirrors {
135154
h := newMirrorRegistryHost(rawMirror)
136155
mirrorHost := h.Host
137-
host, err := fillInsecureOpts(mirrorHost, m[mirrorHost], h)
156+
host, err := fillConfigOpts(mirrorHost, m[mirrorHost], h)
138157
if err != nil {
139158
return nil, err
140159
}
@@ -154,7 +173,7 @@ func NewRegistryConfig(m map[string]config.RegistryConfig) docker.RegistryHosts
154173
Capabilities: docker.HostCapabilityPush | docker.HostCapabilityPull | docker.HostCapabilityResolve,
155174
}
156175

157-
hosts, err := fillInsecureOpts(host, c, h)
176+
hosts, err := fillConfigOpts(host, c, h)
158177
if err != nil {
159178
return nil, err
160179
}

util/resolver/resolver_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"path"
66
"testing"
77

8+
"github.com/containerd/containerd/v2/core/remotes/docker"
89
"github.com/moby/buildkit/cmd/buildkitd/config"
910
"github.com/stretchr/testify/require"
1011
)
@@ -66,3 +67,67 @@ mirrors = ["https://url/", "https://url/path/"]
6667
}
6768
}
6869
}
70+
71+
func TestNewRegistryConfig(t *testing.T) {
72+
const testConfig = `
73+
[registry."docker.io"]
74+
mirrors = ["yourmirror.local", "proxy.local:5000/proxy.docker.io"]
75+
76+
[registry."yourmirror.local"]
77+
http = true
78+
79+
[registry."proxy.local:5000"]
80+
capabilities = ["pull", "resolve", "push"]
81+
`
82+
83+
tests := map[string]struct {
84+
description string
85+
http bool
86+
capabilities docker.HostCapabilities
87+
mirrors []string
88+
scheme string
89+
path string
90+
}{
91+
"registry-1.docker.io": {
92+
description: "valid_docker_io_with_mirrors",
93+
mirrors: []string{"yourmirror.local", "proxy.local:5000", "registry-1.docker.io"},
94+
scheme: "https",
95+
path: defaultPath,
96+
capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve | docker.HostCapabilityPush,
97+
},
98+
"yourmirror.local": {
99+
description: "http_mirror",
100+
scheme: "http",
101+
path: defaultPath,
102+
capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve,
103+
},
104+
"proxy.local:5000": {
105+
description: "proxy_push_mirror",
106+
scheme: "https",
107+
path: path.Join(defaultPath, "proxy.docker.io"),
108+
capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve | docker.HostCapabilityPush,
109+
},
110+
}
111+
112+
cfg, err := config.Load(bytes.NewBuffer([]byte(testConfig)))
113+
require.NoError(t, err)
114+
115+
require.NotEqual(t, 0, len(cfg.Registries))
116+
registryHosts := NewRegistryConfig(cfg.Registries)
117+
require.NotNil(t, registryHosts)
118+
hosts, err := registryHosts("docker.io")
119+
require.NoError(t, err)
120+
hostnames := make([]string, 0, len(hosts))
121+
for _, host := range hosts {
122+
test := tests[host.Host]
123+
desc := test.description
124+
t.Run(desc, func(t *testing.T) {
125+
hostnames = append(hostnames, host.Host)
126+
require.NotNil(t, test, "unexpected registry host: %s", host.Host)
127+
require.Equal(t, test.capabilities, host.Capabilities)
128+
require.Equal(t, test.scheme, host.Scheme)
129+
require.Equal(t, test.path, host.Path)
130+
})
131+
}
132+
require.Equal(t, tests["registry-1.docker.io"].mirrors, hostnames)
133+
}

0 commit comments

Comments
 (0)