Merge pull request #50233 from thaJeztah/validate_mirrors

daemon/config: Validate: add missing validation for registry mirrors and improve errors
This commit is contained in:
Sebastiaan van Stijn
2025-06-20 12:50:48 +02:00
committed by GitHub
4 changed files with 34 additions and 3 deletions

View File

@@ -748,6 +748,12 @@ func Validate(config *Config) error {
}
}
for _, mirror := range config.ServiceOptions.Mirrors {
if _, err := registry.ValidateMirror(mirror); err != nil {
return err
}
}
if config.CorsHeaders != "" {
// TODO(thaJeztah): option is used to produce error when used; remove in next release
return errors.New(`DEPRECATED: The "api-cors-header" config parameter and the dockerd "--api-cors-header" option have been removed; use a reverse proxy if you need CORS headers`)

View File

@@ -14,6 +14,7 @@ import (
"github.com/docker/docker/api"
"github.com/docker/docker/libnetwork/ipamutils"
"github.com/docker/docker/opts"
"github.com/docker/docker/registry"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/spf13/pflag"
@@ -428,6 +429,17 @@ func TestValidateConfigurationErrors(t *testing.T) {
platform: "windows",
expectedErr: "invalid exec-opt (native.cgroupdriver=systemd): option 'native.cgroupdriver' is only supported on linux",
},
{
name: "invalid mirror",
config: &Config{
CommonConfig: CommonConfig{
ServiceOptions: registry.ServiceOptions{
Mirrors: []string{"ftp://example.com"},
},
},
},
expectedErr: `invalid mirror: unsupported scheme "ftp" in "ftp://example.com": must use either 'https://' or 'http://'`,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {

View File

@@ -298,12 +298,17 @@ func isCIDRMatch(cidrs []*registry.NetIPNet, URLHost string) bool {
//
// It is used by the daemon to validate the daemon configuration.
func ValidateMirror(mirrorURL string) (string, error) {
// Fast path for missing scheme, as url.Parse splits by ":", which can
// cause the hostname to be considered the "scheme" when using "hostname:port".
if scheme, _, ok := strings.Cut(mirrorURL, "://"); !ok || scheme == "" {
return "", invalidParamf("invalid mirror: no scheme specified for %q: must use either 'https://' or 'http://'", mirrorURL)
}
uri, err := url.Parse(mirrorURL)
if err != nil {
return "", invalidParamWrapf(err, "invalid mirror: %q is not a valid URI", mirrorURL)
}
if uri.Scheme != "http" && uri.Scheme != "https" {
return "", invalidParamf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri)
return "", invalidParamf("invalid mirror: unsupported scheme %q in %q: must use either 'https://' or 'http://'", uri.Scheme, uri)
}
if uri.RawQuery != "" || uri.Fragment != "" {
return "", invalidParamf("invalid mirror: query or fragment at end of the URI %q", uri)

View File

@@ -77,9 +77,17 @@ func TestValidateMirror(t *testing.T) {
input: "!invalid!://%as%",
expectedErr: `invalid mirror: "!invalid!://%as%" is not a valid URI: parse "!invalid!://%as%": first path segment in URL cannot contain colon`,
},
{
input: "mirror-1.example.com",
expectedErr: `invalid mirror: no scheme specified for "mirror-1.example.com": must use either 'https://' or 'http://'`,
},
{
input: "mirror-1.example.com:5000",
expectedErr: `invalid mirror: no scheme specified for "mirror-1.example.com:5000": must use either 'https://' or 'http://'`,
},
{
input: "ftp://mirror-1.example.com",
expectedErr: `invalid mirror: unsupported scheme "ftp" in "ftp://mirror-1.example.com"`,
expectedErr: `invalid mirror: unsupported scheme "ftp" in "ftp://mirror-1.example.com": must use either 'https://' or 'http://'`,
},
{
input: "http://mirror-1.example.com/?q=foo",
@@ -235,7 +243,7 @@ func TestNewServiceConfig(t *testing.T) {
opts: ServiceOptions{
Mirrors: []string{"example.com:5000"},
},
errStr: `invalid mirror: unsupported scheme "example.com" in "example.com:5000"`,
errStr: `invalid mirror: no scheme specified for "example.com:5000": must use either 'https://' or 'http://'`,
},
{
doc: "valid mirror",