remove support for non-distributable artifacts and deprecate API fields and config

Non-distributable artifacts (foreign layers) were introduced in commit
05bd04350b to accommodate Windows images,
for which the EULA did not allow layers to be distributed through registries
other than those hosted by Microsoft. The concept of foreign / non-distributable
layers was adopted by the OCI distribution spec in [oci#233].

These restrictions were relaxed later to allow distributing these images
through non-public registries, for which a configuration was added in the
daemon in 67fdf574d5. In 2022, Microsoft updated
the EULA and [removed these restrictions altogether][1], and the OCI distribution
spec deprecated the  functionality in [oci#965].

In 2023, Microsoft [removed the use of foreign data layers][2] for their images,
making this functionality obsolete.

This patch:

- Deprecates the `--allow-nondistributable-artifacts` daemon flag and corresponding
  `allow-nondistributable-artifacts` field in `daemon.json`. Setting either
  option will no longer take an effect, but a deprecation warning log is added
  to raise awareness about the deprecation. This warning is planned to become
  an error in the next release.
- Deprecates the `RegistryConfig.AllowNondistributableArtifactsCIDRs` and
  `RegistryConfig.AllowNondistributableArtifactsHostnames` fields in the
  `GET /info` API response. For API version v1.48 and lower, the fields are
  still included in the response, but always `null`. In API version v1.49 and
  higher, the field will be omitted entirely.
- Deprecates the `api/types/registry/ServiceConfig.AllowNondistributableArtifactsCIDRs`
  field.
- Deprecates the `api/types/registry/ServiceConfig.AllowNondistributableArtifactsHostnames`
  field.
- Deprecates the `registry.ServiceOptions.AllowNondistributableArtifacts` field.

[oci#233]: https://github.com/opencontainers/image-spec/pull/233
[oci#965]: https://github.com/opencontainers/image-spec/pull/965
[1]: https://techcommunity.microsoft.com/blog/containers/announcing-windows-container-base-image-redistribution-rights-change/3645201
[2]: https://techcommunity.microsoft.com/blog/containers/announcing-removal-of-foreign-layers-from-windows-container-images/3846833

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2024-12-03 13:32:46 +01:00
parent 7faa4ecfbf
commit 1932091e21
18 changed files with 111 additions and 392 deletions

View File

@@ -100,6 +100,12 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
// Containerd field introduced in API v1.46.
info.Containerd = nil
}
if versions.LessThan(version, "1.47") {
// Field is omitted in API 1.48 and up, but should still be included
// in older versions, even if no values are set.
info.RegistryConfig.AllowNondistributableArtifactsCIDRs = []*registry.NetIPNet{}
info.RegistryConfig.AllowNondistributableArtifactsHostnames = []string{}
}
// TODO(thaJeztah): Expected commits are deprecated, and should no longer be set in API 1.49.
info.ContainerdCommit.Expected = info.ContainerdCommit.ID //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.49.

View File

@@ -5983,55 +5983,27 @@ definitions:
List of IP ranges to which nondistributable artifacts can be pushed,
using the CIDR syntax [RFC 4632](https://tools.ietf.org/html/4632).
Some images (for example, Windows base images) contain artifacts
whose distribution is restricted by license. When these images are
pushed to a registry, restricted artifacts are not included.
This configuration override this behavior, and enables the daemon to
push nondistributable artifacts to all registries whose resolved IP
address is within the subnet described by the CIDR syntax.
This option is useful when pushing images containing
nondistributable artifacts to a registry on an air-gapped network so
hosts on that network can pull the images without connecting to
another server.
> **Warning**: Nondistributable artifacts typically have restrictions
> on how and where they can be distributed and shared. Only use this
> feature to push artifacts to private registries and ensure that you
> are in compliance with any terms that cover redistributing
> nondistributable artifacts.
<p><br /></p>
> **Deprecated**: Pushing nondistributable artifacts is now always enabled
> and this field is always `null`. This field will be removed in a API v1.49.
type: "array"
items:
type: "string"
example: ["::1/128", "127.0.0.0/8"]
example: []
AllowNondistributableArtifactsHostnames:
description: |
List of registry hostnames to which nondistributable artifacts can be
pushed, using the format `<hostname>[:<port>]` or `<IP address>[:<port>]`.
Some images (for example, Windows base images) contain artifacts
whose distribution is restricted by license. When these images are
pushed to a registry, restricted artifacts are not included.
<p><br /></p>
This configuration override this behavior for the specified
registries.
This option is useful when pushing images containing
nondistributable artifacts to a registry on an air-gapped network so
hosts on that network can pull the images without connecting to
another server.
> **Warning**: Nondistributable artifacts typically have restrictions
> on how and where they can be distributed and shared. Only use this
> feature to push artifacts to private registries and ensure that you
> are in compliance with any terms that cover redistributing
> nondistributable artifacts.
> **Deprecated**: Pushing nondistributable artifacts is now always enabled
> and this field is always `null`. This field will be removed in a API v1.49.
type: "array"
items:
type: "string"
example: ["registry.internal.corp.example.com:3000", "[2001:db8:a0b:12f0::1]:443"]
example: []
InsecureRegistryCIDRs:
description: |
List of IP ranges of insecure registries, using the CIDR syntax

View File

@@ -9,11 +9,29 @@ import (
// ServiceConfig stores daemon registry services configuration.
type ServiceConfig struct {
AllowNondistributableArtifactsCIDRs []*NetIPNet
AllowNondistributableArtifactsHostnames []string
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
Mirrors []string
AllowNondistributableArtifactsCIDRs []*NetIPNet `json:"AllowNondistributableArtifactsCIDRs,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
AllowNondistributableArtifactsHostnames []string `json:"AllowNondistributableArtifactsHostnames,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
Mirrors []string
}
// MarshalJSON implements a custom marshaler to include legacy fields
// in API responses.
func (sc ServiceConfig) MarshalJSON() ([]byte, error) {
tmp := map[string]interface{}{
"InsecureRegistryCIDRs": sc.InsecureRegistryCIDRs,
"IndexConfigs": sc.IndexConfigs,
"Mirrors": sc.Mirrors,
}
if sc.AllowNondistributableArtifactsCIDRs != nil {
tmp["AllowNondistributableArtifactsCIDRs"] = nil
}
if sc.AllowNondistributableArtifactsHostnames != nil {
tmp["AllowNondistributableArtifactsHostnames"] = nil
}
return json.Marshal(tmp)
}
// NetIPNet is the net.IPNet type, which can be marshalled and

View File

@@ -0,0 +1,30 @@
package registry
import (
"encoding/json"
"testing"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestServiceConfigMarshalLegacyFields(t *testing.T) {
t.Run("without legacy fields", func(t *testing.T) {
b, err := json.Marshal(&ServiceConfig{})
assert.NilError(t, err)
const expected = `{"IndexConfigs":null,"InsecureRegistryCIDRs":null,"Mirrors":null}`
assert.Check(t, is.Equal(string(b), expected), "Legacy nondistributable-artifacts fields should be omitted in output")
})
// Legacy fields should be returned when set to an empty slice. This is
// used for API versions < 1.49.
t.Run("with legacy fields", func(t *testing.T) {
b, err := json.Marshal(&ServiceConfig{
AllowNondistributableArtifactsCIDRs: []*NetIPNet{},
AllowNondistributableArtifactsHostnames: []string{},
})
assert.NilError(t, err)
const expected = `{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"IndexConfigs":null,"InsecureRegistryCIDRs":null,"Mirrors":null}`
assert.Check(t, is.Equal(string(b), expected))
})
}

View File

@@ -18,6 +18,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
insecureRegistries = opts.NewNamedListOptsRef("insecure-registries", &conf.InsecureRegistries, registry.ValidateIndexName)
)
flags.Var(allowNonDistributable, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry")
_ = flags.MarkDeprecated("allow-nondistributable-artifacts", "Pushing nondistributable artifacts is now enabled by default. ")
flags.Var(registryMirrors, "registry-mirror", "Preferred Docker registry mirror")
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")

View File

@@ -653,6 +653,11 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
return nil, err
}
if len(conf.AllowNondistributableArtifacts) > 0 {
// TODO(thaJeztah): move to config.Validate and change into an error for v29.0 and remove in v30.0.
log.G(context.TODO()).Warn(`DEPRECATED: The "allow-nondistributable-artifacts" config parameter is deprecated and always enabled; this option will be removed in the next release`)
}
return conf, nil
}

View File

@@ -190,7 +190,6 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
content := `{
"allow-nondistributable-artifacts": ["allow-nondistributable-artifacts.example.com"],
"registry-mirrors": ["https://mirrors.example.com"],
"insecure-registries": ["https://insecure-registry.example.com"]
}`
@@ -202,7 +201,6 @@ func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
assert.NilError(t, err)
assert.Assert(t, loadedConfig != nil)
assert.Check(t, is.Len(loadedConfig.AllowNondistributableArtifacts, 1))
assert.Check(t, is.Len(loadedConfig.Mirrors, 1))
assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1))
}

View File

@@ -231,10 +231,6 @@ func (daemon *Daemon) reloadLabels(txn *reloadTxn, newCfg *configStore, conf *co
// reloadRegistryConfig updates the configuration with registry options
// and updates the passed attributes.
func (daemon *Daemon) reloadRegistryConfig(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
// Update corresponding configuration.
if conf.IsValueSet("allow-nondistributable-artifacts") {
newCfg.ServiceOptions.AllowNondistributableArtifacts = conf.AllowNondistributableArtifacts
}
if conf.IsValueSet("insecure-registries") {
newCfg.ServiceOptions.InsecureRegistries = conf.InsecureRegistries
}
@@ -248,7 +244,6 @@ func (daemon *Daemon) reloadRegistryConfig(txn *reloadTxn, newCfg *configStore,
}
txn.OnCommit(func() error { commit(); return nil })
attributes["allow-nondistributable-artifacts"] = marshalAttributeSlice(newCfg.ServiceOptions.AllowNondistributableArtifacts)
attributes["insecure-registries"] = marshalAttributeSlice(newCfg.ServiceOptions.InsecureRegistries)
attributes["registry-mirrors"] = marshalAttributeSlice(newCfg.ServiceOptions.Mirrors)

View File

@@ -2,7 +2,6 @@ package daemon // import "github.com/docker/docker/daemon"
import (
"os"
"sort"
"testing"
"github.com/containerd/log"
@@ -11,7 +10,6 @@ import (
"github.com/docker/docker/libnetwork"
"github.com/docker/docker/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
// muteLogs suppresses logs that are generated during the test
@@ -62,61 +60,6 @@ func TestDaemonReloadLabels(t *testing.T) {
}
}
func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) {
daemon := newDaemonForReloadT(t, &config.Config{})
muteLogs(t)
var err error
// Initialize daemon with some registries.
daemon.registryService, err = registry.NewService(registry.ServiceOptions{
AllowNondistributableArtifacts: []string{
"127.0.0.0/8",
"10.10.1.11:5000",
"10.10.1.22:5000", // This will be removed during reload.
"docker1.com",
"docker2.com", // This will be removed during reload.
},
})
if err != nil {
t.Fatal(err)
}
registries := []string{
"::1/128",
"127.0.0.0/8",
"10.10.1.11:5000",
"10.10.1.33:5000", // This will be added during reload.
"docker1.com",
"docker3.com", // This will be added during reload.
}
newConfig := &config.Config{
CommonConfig: config.CommonConfig{
ServiceOptions: registry.ServiceOptions{
AllowNondistributableArtifacts: registries,
},
ValuesSet: map[string]interface{}{
"allow-nondistributable-artifacts": registries,
},
},
}
if err := daemon.Reload(newConfig); err != nil {
t.Fatal(err)
}
var actual []string
serviceConfig := daemon.registryService.ServiceConfig()
for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs {
actual = append(actual, value.String())
}
actual = append(actual, serviceConfig.AllowNondistributableArtifactsHostnames...)
sort.Strings(registries)
sort.Strings(actual)
assert.Check(t, is.DeepEqual(registries, actual))
}
func TestDaemonReloadMirrors(t *testing.T) {
daemon := &Daemon{
imageService: images.NewImageService(images.ImageServiceConfig{}),

View File

@@ -297,16 +297,6 @@ func (pd *pushDescriptor) DiffID() layer.DiffID {
}
func (pd *pushDescriptor) Upload(ctx context.Context, progressOutput progress.Output) (distribution.Descriptor, error) {
// Skip foreign layers unless this registry allows nondistributable artifacts.
if !pd.endpoint.AllowNondistributableArtifacts {
if fs, ok := pd.layer.(distribution.Describable); ok {
if d := fs.Descriptor(); len(d.URLs) > 0 {
progress.Update(progressOutput, pd.ID(), "Skipped foreign layer")
return d, nil
}
}
}
diffID := pd.DiffID()
pd.pushState.Lock()

View File

@@ -17,6 +17,11 @@ keywords: "API, Docker, rcli, REST, documentation"
[Docker Engine API v1.48](https://docs.docker.com/reference/api/engine/version/v1.48/) documentation
# Deprecated: The "allow-nondistributable-artifacts" daemon configuration is
deprecated and enabled by default. The `AllowNondistributableArtifactsCIDRs`
and `AllowNondistributableArtifactsHostnames` fields in the `RegistryConfig`
struct in the `GET /info` response will now always be `null` and will be
omitted in API v1.49.
* `GET /images/{name}/history` now supports a `platform` parameter (JSON
encoded OCI Platform type) that allows to specify a platform to show the
history of.

View File

@@ -414,8 +414,7 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *testing.T) {
// otherwise just check for names being present.
expectedSubstrings := []string{
` daemon reload ` + info.ID + " ",
`(allow-nondistributable-artifacts=[`,
` debug=true, `,
`debug=true, `,
` default-ipc-mode=`,
` default-runtime=`,
` default-shm-size=`,

View File

@@ -6,7 +6,6 @@ dockerd - Enable daemon mode
# SYNOPSIS
**dockerd**
[**--add-runtime**[=*[]*]]
[**--allow-nondistributable-artifacts**[=*[]*]]
[**--authorization-plugin**[=*[]*]]
[**-b**|**--bridge**[=*BRIDGE*]]
[**--bip**[=*BIP*]]

View File

@@ -15,9 +15,10 @@ import (
// ServiceOptions holds command line options.
type ServiceOptions struct {
AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"`
Mirrors []string `json:"registry-mirrors,omitempty"`
InsecureRegistries []string `json:"insecure-registries,omitempty"`
AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
Mirrors []string `json:"registry-mirrors,omitempty"`
InsecureRegistries []string `json:"insecure-registries,omitempty"`
}
// serviceConfig holds daemon configuration for the registry service.
@@ -80,9 +81,6 @@ func CertsDir() string {
// newServiceConfig returns a new instance of ServiceConfig
func newServiceConfig(options ServiceOptions) (*serviceConfig, error) {
config := &serviceConfig{}
if err := config.loadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil {
return nil, err
}
if err := config.loadMirrors(options.Mirrors); err != nil {
return nil, err
}
@@ -100,51 +98,12 @@ func (config *serviceConfig) copy() *registry.ServiceConfig {
ic[key] = value
}
return &registry.ServiceConfig{
AllowNondistributableArtifactsCIDRs: append([]*registry.NetIPNet(nil), config.AllowNondistributableArtifactsCIDRs...),
AllowNondistributableArtifactsHostnames: append([]string(nil), config.AllowNondistributableArtifactsHostnames...),
InsecureRegistryCIDRs: append([]*registry.NetIPNet(nil), config.InsecureRegistryCIDRs...),
IndexConfigs: ic,
Mirrors: append([]string(nil), config.Mirrors...),
InsecureRegistryCIDRs: append([]*registry.NetIPNet(nil), config.InsecureRegistryCIDRs...),
IndexConfigs: ic,
Mirrors: append([]string(nil), config.Mirrors...),
}
}
// loadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config.
func (config *serviceConfig) loadAllowNondistributableArtifacts(registries []string) error {
cidrs := map[string]*registry.NetIPNet{}
hostnames := map[string]bool{}
for _, r := range registries {
if _, err := ValidateIndexName(r); err != nil {
return err
}
if hasScheme(r) {
return invalidParamf("allow-nondistributable-artifacts registry %s should not contain '://'", r)
}
if _, ipnet, err := net.ParseCIDR(r); err == nil {
// Valid CIDR.
cidrs[ipnet.String()] = (*registry.NetIPNet)(ipnet)
} else if err = validateHostPort(r); err == nil {
// Must be `host:port` if not CIDR.
hostnames[r] = true
} else {
return invalidParamWrapf(err, "allow-nondistributable-artifacts registry %s is not valid", r)
}
}
config.AllowNondistributableArtifactsCIDRs = make([]*registry.NetIPNet, 0, len(cidrs))
for _, c := range cidrs {
config.AllowNondistributableArtifactsCIDRs = append(config.AllowNondistributableArtifactsCIDRs, c)
}
config.AllowNondistributableArtifactsHostnames = make([]string, 0, len(hostnames))
for h := range hostnames {
config.AllowNondistributableArtifactsHostnames = append(config.AllowNondistributableArtifactsHostnames, h)
}
return nil
}
// loadMirrors loads mirrors to config, after removing duplicates.
// Returns an error if mirrors contains an invalid mirror.
func (config *serviceConfig) loadMirrors(mirrors []string) error {
@@ -242,25 +201,6 @@ skip:
return nil
}
// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries
// that allow push of nondistributable artifacts.
//
// The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP
// of the registry specified by hostname, true is returned.
//
// hostname should be a URL.Host (`host:port` or `host`) where the `host` part can be either a domain name
// or an IP address. If it is a domain name, then it will be resolved to IP addresses for matching. If
// resolution fails, CIDR matching is not performed.
func (config *serviceConfig) allowNondistributableArtifacts(hostname string) bool {
for _, h := range config.AllowNondistributableArtifactsHostnames {
if h == hostname {
return true
}
}
return isCIDRMatch(config.AllowNondistributableArtifactsCIDRs, hostname)
}
// isSecureIndex returns false if the provided indexName is part of the list of insecure registries
// Insecure registries accept HTTP and/or accept HTTPS with certificates from unknown CAs.
//

View File

@@ -1,9 +1,6 @@
package registry // import "github.com/docker/docker/registry"
import (
"reflect"
"sort"
"strings"
"testing"
"github.com/docker/docker/errdefs"
@@ -11,123 +8,6 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func TestLoadAllowNondistributableArtifacts(t *testing.T) {
testCases := []struct {
registries []string
cidrStrs []string
hostnames []string
err string
}{
{
registries: []string{"1.2.3.0/24"},
cidrStrs: []string{"1.2.3.0/24"},
},
{
registries: []string{"2001:db8::/120"},
cidrStrs: []string{"2001:db8::/120"},
},
{
registries: []string{"127.0.0.1"},
hostnames: []string{"127.0.0.1"},
},
{
registries: []string{"127.0.0.1:8080"},
hostnames: []string{"127.0.0.1:8080"},
},
{
registries: []string{"2001:db8::1"},
hostnames: []string{"2001:db8::1"},
},
{
registries: []string{"[2001:db8::1]:80"},
hostnames: []string{"[2001:db8::1]:80"},
},
{
registries: []string{"[2001:db8::1]:80"},
hostnames: []string{"[2001:db8::1]:80"},
},
{
registries: []string{"1.2.3.0/24", "2001:db8::/120", "127.0.0.1", "127.0.0.1:8080"},
cidrStrs: []string{"1.2.3.0/24", "2001:db8::/120"},
hostnames: []string{"127.0.0.1", "127.0.0.1:8080"},
},
{
registries: []string{"http://myregistry.example.com"},
err: "allow-nondistributable-artifacts registry http://myregistry.example.com should not contain '://'",
},
{
registries: []string{"https://myregistry.example.com"},
err: "allow-nondistributable-artifacts registry https://myregistry.example.com should not contain '://'",
},
{
registries: []string{"HTTP://myregistry.example.com"},
err: "allow-nondistributable-artifacts registry HTTP://myregistry.example.com should not contain '://'",
},
{
registries: []string{"svn://myregistry.example.com"},
err: "allow-nondistributable-artifacts registry svn://myregistry.example.com should not contain '://'",
},
{
registries: []string{"-invalid-registry"},
err: "Cannot begin or end with a hyphen",
},
{
registries: []string{`mytest-.com`},
err: `allow-nondistributable-artifacts registry mytest-.com is not valid: invalid host "mytest-.com"`,
},
{
registries: []string{`1200:0000:AB00:1234:0000:2552:7777:1313:8080`},
err: `allow-nondistributable-artifacts registry 1200:0000:AB00:1234:0000:2552:7777:1313:8080 is not valid: invalid host "1200:0000:AB00:1234:0000:2552:7777:1313:8080"`,
},
{
registries: []string{`myregistry.example.com:500000`},
err: `allow-nondistributable-artifacts registry myregistry.example.com:500000 is not valid: invalid port "500000"`,
},
{
registries: []string{`"myregistry.example.com"`},
err: `allow-nondistributable-artifacts registry "myregistry.example.com" is not valid: invalid host "\"myregistry.example.com\""`,
},
{
registries: []string{`"myregistry.example.com:5000"`},
err: `allow-nondistributable-artifacts registry "myregistry.example.com:5000" is not valid: invalid host "\"myregistry.example.com"`,
},
}
for _, testCase := range testCases {
config := emptyServiceConfig
err := config.loadAllowNondistributableArtifacts(testCase.registries)
if testCase.err == "" {
if err != nil {
t.Fatalf("expect no error, got '%s'", err)
}
var cidrStrs []string
for _, c := range config.AllowNondistributableArtifactsCIDRs {
cidrStrs = append(cidrStrs, c.String())
}
sort.Strings(testCase.cidrStrs)
sort.Strings(cidrStrs)
if (len(testCase.cidrStrs) > 0 || len(cidrStrs) > 0) && !reflect.DeepEqual(testCase.cidrStrs, cidrStrs) {
t.Fatalf("expect AllowNondistributableArtifactsCIDRs to be '%+v', got '%+v'", testCase.cidrStrs, cidrStrs)
}
sort.Strings(testCase.hostnames)
sort.Strings(config.AllowNondistributableArtifactsHostnames)
if (len(testCase.hostnames) > 0 || len(config.AllowNondistributableArtifactsHostnames) > 0) && !reflect.DeepEqual(testCase.hostnames, config.AllowNondistributableArtifactsHostnames) {
t.Fatalf("expect AllowNondistributableArtifactsHostnames to be '%+v', got '%+v'", testCase.hostnames, config.AllowNondistributableArtifactsHostnames)
}
} else {
if err == nil {
t.Fatalf("expect error '%s', got no error", testCase.err)
}
if !strings.Contains(err.Error(), testCase.err) {
t.Fatalf("expect error '%s', got '%s'", testCase.err, err)
}
}
}
}
func TestValidateMirror(t *testing.T) {
valid := []string{
"http://mirror-1.example.com",
@@ -263,60 +143,52 @@ func TestLoadInsecureRegistries(t *testing.T) {
}
func TestNewServiceConfig(t *testing.T) {
testCases := []struct {
tests := []struct {
doc string
opts ServiceOptions
errStr string
}{
{
ServiceOptions{},
"",
doc: "empty config",
},
{
ServiceOptions{
doc: "invalid mirror",
opts: ServiceOptions{
Mirrors: []string{"example.com:5000"},
},
`invalid mirror: unsupported scheme "example.com" in "example.com:5000"`,
errStr: `invalid mirror: unsupported scheme "example.com" in "example.com:5000"`,
},
{
ServiceOptions{
Mirrors: []string{"http://example.com:5000"},
doc: "valid mirror",
opts: ServiceOptions{
Mirrors: []string{"https://example.com:5000"},
},
"",
},
{
ServiceOptions{
doc: "invalid insecure registry",
opts: ServiceOptions{
InsecureRegistries: []string{"[fe80::]/64"},
},
`insecure registry [fe80::]/64 is not valid: invalid host "[fe80::]/64"`,
errStr: `insecure registry [fe80::]/64 is not valid: invalid host "[fe80::]/64"`,
},
{
ServiceOptions{
doc: "valid insecure registry",
opts: ServiceOptions{
InsecureRegistries: []string{"102.10.8.1/24"},
},
"",
},
{
ServiceOptions{
AllowNondistributableArtifacts: []string{"[fe80::]/64"},
},
`allow-nondistributable-artifacts registry [fe80::]/64 is not valid: invalid host "[fe80::]/64"`,
},
{
ServiceOptions{
AllowNondistributableArtifacts: []string{"102.10.8.1/24"},
},
"",
},
}
for _, testCase := range testCases {
_, err := newServiceConfig(testCase.opts)
if testCase.errStr != "" {
assert.Check(t, is.Error(err, testCase.errStr))
assert.Check(t, errdefs.IsInvalidParameter(err))
} else {
assert.Check(t, err)
}
for _, tc := range tests {
t.Run(tc.doc, func(t *testing.T) {
_, err := newServiceConfig(tc.opts)
if tc.errStr != "" {
assert.Check(t, is.Error(err, tc.errStr))
assert.Check(t, errdefs.IsInvalidParameter(err))
} else {
assert.Check(t, err)
}
})
}
}

View File

@@ -440,52 +440,6 @@ func TestMirrorEndpointLookup(t *testing.T) {
}
}
func TestAllowNondistributableArtifacts(t *testing.T) {
overrideLookupIP(t)
tests := []struct {
addr string
registries []string
expected bool
}{
{IndexName, nil, false},
{"example.com", []string{}, false},
{"example.com", []string{"example.com"}, true},
{"localhost", []string{"localhost:5000"}, false},
{"localhost:5000", []string{"localhost:5000"}, true},
{"localhost", []string{"example.com"}, false},
{"127.0.0.1:5000", []string{"127.0.0.1:5000"}, true},
{"localhost", nil, false},
{"localhost:5000", nil, false},
{"127.0.0.1", nil, false},
{"localhost", []string{"example.com"}, false},
{"127.0.0.1", []string{"example.com"}, false},
{"example.com", nil, false},
{"example.com", []string{"example.com"}, true},
{"127.0.0.1", []string{"example.com"}, false},
{"127.0.0.1:5000", []string{"example.com"}, false},
{"example.com:5000", []string{"42.42.0.0/16"}, true},
{"example.com", []string{"42.42.0.0/16"}, true},
{"example.com:5000", []string{"42.42.42.42/8"}, true},
{"127.0.0.1:5000", []string{"127.0.0.0/8"}, true},
{"42.42.42.42:5000", []string{"42.1.1.1/8"}, true},
{"invalid.example.com", []string{"42.42.0.0/16"}, false},
{"invalid.example.com", []string{"invalid.example.com"}, true},
{"invalid.example.com:5000", []string{"invalid.example.com"}, false},
{"invalid.example.com:5000", []string{"invalid.example.com:5000"}, true},
}
for _, tt := range tests {
config, err := newServiceConfig(ServiceOptions{
AllowNondistributableArtifacts: tt.registries,
})
if err != nil {
t.Error(err)
}
if v := config.allowNondistributableArtifacts(tt.addr); v != tt.expected {
t.Errorf("allowNondistributableArtifacts failed for %q %v, expected %v got %v", tt.addr, tt.registries, tt.expected, v)
}
}
}
func TestIsSecureIndex(t *testing.T) {
overrideLookupIP(t)
tests := []struct {

View File

@@ -104,7 +104,7 @@ func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, erro
type APIEndpoint struct {
Mirror bool
URL *url.URL
AllowNondistributableArtifacts bool
AllowNondistributableArtifacts bool // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
Official bool
TrimHostname bool // Deprecated: hostname is now trimmed unconditionally for remote names. This field will be removed in the next release.
TLSConfig *tls.Config

View File

@@ -8,8 +8,6 @@ import (
)
func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]APIEndpoint, error) {
ana := s.config.allowNondistributableArtifacts(hostname)
var endpoints []APIEndpoint
if hostname == DefaultNamespace || hostname == IndexHostname {
if includeMirrors {
@@ -36,8 +34,6 @@ func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]API
URL: DefaultV2Registry,
Official: true,
TLSConfig: tlsconfig.ServerDefault(),
AllowNondistributableArtifacts: ana,
})
return endpoints, nil
@@ -55,8 +51,6 @@ func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]API
Host: hostname,
},
TLSConfig: tlsConfig,
AllowNondistributableArtifacts: ana,
},
}
@@ -68,8 +62,6 @@ func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]API
},
// used to check if supposed to be secure via InsecureSkipVerify
TLSConfig: tlsConfig,
AllowNondistributableArtifacts: ana,
})
}