Skip to content

Commit af42d6d

Browse files
committed
remove support for non-distributable artifacts and deprecate API fields and config
Non-distributable artifacts (foreign layers) were introduced in commit 05bd043 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 67fdf57. 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]: opencontainers/image-spec#233 [oci#965]: opencontainers/image-spec#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 <[email protected]>
1 parent 9633556 commit af42d6d

File tree

16 files changed

+109
-380
lines changed

16 files changed

+109
-380
lines changed

api/server/router/system/system_routes.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
100100
// Containerd field introduced in API v1.46.
101101
info.Containerd = nil
102102
}
103+
if versions.LessThan(version, "1.47") {
104+
// Field is omitted in API 1.48 and up, but should still be included
105+
// in older versions, even if no values are set.
106+
info.RegistryConfig.AllowNondistributableArtifactsCIDRs = []*registry.NetIPNet{}
107+
info.RegistryConfig.AllowNondistributableArtifactsHostnames = []string{}
108+
}
103109

104110
// TODO(thaJeztah): Expected commits are deprecated, and should no longer be set in API 1.49.
105111
info.ContainerdCommit.Expected = info.ContainerdCommit.ID //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.49.

api/swagger.yaml

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5983,55 +5983,27 @@ definitions:
59835983
List of IP ranges to which nondistributable artifacts can be pushed,
59845984
using the CIDR syntax [RFC 4632](https://tools.ietf.org/html/4632).
59855985
5986-
Some images (for example, Windows base images) contain artifacts
5987-
whose distribution is restricted by license. When these images are
5988-
pushed to a registry, restricted artifacts are not included.
5989-
5990-
This configuration override this behavior, and enables the daemon to
5991-
push nondistributable artifacts to all registries whose resolved IP
5992-
address is within the subnet described by the CIDR syntax.
5993-
5994-
This option is useful when pushing images containing
5995-
nondistributable artifacts to a registry on an air-gapped network so
5996-
hosts on that network can pull the images without connecting to
5997-
another server.
5998-
5999-
> **Warning**: Nondistributable artifacts typically have restrictions
6000-
> on how and where they can be distributed and shared. Only use this
6001-
> feature to push artifacts to private registries and ensure that you
6002-
> are in compliance with any terms that cover redistributing
6003-
> nondistributable artifacts.
5986+
<p><br /></p>
60045987
5988+
> **Deprecated**: Pushing nondistributable artifacts is now always enabled
5989+
> and this field is always `null`. This field will be removed in a API v1.49.
60055990
type: "array"
60065991
items:
60075992
type: "string"
6008-
example: ["::1/128", "127.0.0.0/8"]
5993+
example: []
60095994
AllowNondistributableArtifactsHostnames:
60105995
description: |
60115996
List of registry hostnames to which nondistributable artifacts can be
60125997
pushed, using the format `<hostname>[:<port>]` or `<IP address>[:<port>]`.
60135998
6014-
Some images (for example, Windows base images) contain artifacts
6015-
whose distribution is restricted by license. When these images are
6016-
pushed to a registry, restricted artifacts are not included.
6017-
6018-
This configuration override this behavior for the specified
6019-
registries.
6020-
6021-
This option is useful when pushing images containing
6022-
nondistributable artifacts to a registry on an air-gapped network so
6023-
hosts on that network can pull the images without connecting to
6024-
another server.
5999+
<p><br /></p>
60256000
6026-
> **Warning**: Nondistributable artifacts typically have restrictions
6027-
> on how and where they can be distributed and shared. Only use this
6028-
> feature to push artifacts to private registries and ensure that you
6029-
> are in compliance with any terms that cover redistributing
6030-
> nondistributable artifacts.
6001+
> **Deprecated**: Pushing nondistributable artifacts is now always enabled
6002+
> and this field is always `null`. This field will be removed in a API v1.49.
60316003
type: "array"
60326004
items:
60336005
type: "string"
6034-
example: ["registry.internal.corp.example.com:3000", "[2001:db8:a0b:12f0::1]:443"]
6006+
example: []
60356007
InsecureRegistryCIDRs:
60366008
description: |
60376009
List of IP ranges of insecure registries, using the CIDR syntax

api/types/registry/registry.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,29 @@ import (
99

1010
// ServiceConfig stores daemon registry services configuration.
1111
type ServiceConfig struct {
12-
AllowNondistributableArtifactsCIDRs []*NetIPNet
13-
AllowNondistributableArtifactsHostnames []string
14-
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
15-
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
16-
Mirrors []string
12+
AllowNondistributableArtifactsCIDRs []*NetIPNet `json:"AllowNondistributableArtifactsCIDRs,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
13+
AllowNondistributableArtifactsHostnames []string `json:"AllowNondistributableArtifactsHostnames,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
14+
15+
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
16+
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
17+
Mirrors []string
18+
}
19+
20+
// MarshalJSON implements a custom marshaler to include legacy fields
21+
// in API responses.
22+
func (sc ServiceConfig) MarshalJSON() ([]byte, error) {
23+
tmp := map[string]interface{}{
24+
"InsecureRegistryCIDRs": sc.InsecureRegistryCIDRs,
25+
"IndexConfigs": sc.IndexConfigs,
26+
"Mirrors": sc.Mirrors,
27+
}
28+
if sc.AllowNondistributableArtifactsCIDRs != nil {
29+
tmp["AllowNondistributableArtifactsCIDRs"] = nil
30+
}
31+
if sc.AllowNondistributableArtifactsHostnames != nil {
32+
tmp["AllowNondistributableArtifactsHostnames"] = nil
33+
}
34+
return json.Marshal(tmp)
1735
}
1836

1937
// NetIPNet is the net.IPNet type, which can be marshalled and
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package registry
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"gotest.tools/v3/assert"
8+
is "gotest.tools/v3/assert/cmp"
9+
)
10+
11+
func TestServiceConfigMarshalLegacyFields(t *testing.T) {
12+
t.Run("without legacy fields", func(t *testing.T) {
13+
b, err := json.Marshal(&ServiceConfig{})
14+
assert.NilError(t, err)
15+
const expected = `{"IndexConfigs":null,"InsecureRegistryCIDRs":null,"Mirrors":null}`
16+
assert.Check(t, is.Equal(string(b), expected), "Legacy nondistributable-artifacts fields should be omitted in output")
17+
})
18+
19+
// Legacy fields should be returned when set to an empty slice. This is
20+
// used for API versions < 1.49.
21+
t.Run("with legacy fields", func(t *testing.T) {
22+
b, err := json.Marshal(&ServiceConfig{
23+
AllowNondistributableArtifactsCIDRs: []*NetIPNet{},
24+
AllowNondistributableArtifactsHostnames: []string{},
25+
})
26+
assert.NilError(t, err)
27+
const expected = `{"AllowNondistributableArtifactsCIDRs":null,"AllowNondistributableArtifactsHostnames":null,"IndexConfigs":null,"InsecureRegistryCIDRs":null,"Mirrors":null}`
28+
assert.Check(t, is.Equal(string(b), expected))
29+
})
30+
}

cmd/dockerd/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
1818
insecureRegistries = opts.NewNamedListOptsRef("insecure-registries", &conf.InsecureRegistries, registry.ValidateIndexName)
1919
)
2020
flags.Var(allowNonDistributable, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry")
21+
_ = flags.MarkDeprecated("allow-nondistributable-artifacts", "Pushing nondistributable artifacts is now enabled by default. ")
2122
flags.Var(registryMirrors, "registry-mirror", "Preferred Docker registry mirror")
2223
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
2324

cmd/dockerd/daemon.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,11 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
653653
return nil, err
654654
}
655655

656+
if len(conf.AllowNondistributableArtifacts) > 0 {
657+
// TODO(thaJeztah): move to config.Validate and change into an error for v29.0 and remove in v30.0.
658+
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`)
659+
}
660+
656661
return conf, nil
657662
}
658663

cmd/dockerd/daemon_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
190190

191191
func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
192192
content := `{
193-
"allow-nondistributable-artifacts": ["allow-nondistributable-artifacts.example.com"],
194193
"registry-mirrors": ["https://mirrors.example.com"],
195194
"insecure-registries": ["https://insecure-registry.example.com"]
196195
}`
@@ -202,7 +201,6 @@ func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
202201
assert.NilError(t, err)
203202
assert.Assert(t, loadedConfig != nil)
204203

205-
assert.Check(t, is.Len(loadedConfig.AllowNondistributableArtifacts, 1))
206204
assert.Check(t, is.Len(loadedConfig.Mirrors, 1))
207205
assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1))
208206
}

daemon/reload.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,6 @@ func (daemon *Daemon) reloadLabels(txn *reloadTxn, newCfg *configStore, conf *co
231231
// reloadRegistryConfig updates the configuration with registry options
232232
// and updates the passed attributes.
233233
func (daemon *Daemon) reloadRegistryConfig(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
234-
// Update corresponding configuration.
235-
if conf.IsValueSet("allow-nondistributable-artifacts") {
236-
newCfg.ServiceOptions.AllowNondistributableArtifacts = conf.AllowNondistributableArtifacts
237-
}
238234
if conf.IsValueSet("insecure-registries") {
239235
newCfg.ServiceOptions.InsecureRegistries = conf.InsecureRegistries
240236
}
@@ -248,7 +244,6 @@ func (daemon *Daemon) reloadRegistryConfig(txn *reloadTxn, newCfg *configStore,
248244
}
249245
txn.OnCommit(func() error { commit(); return nil })
250246

251-
attributes["allow-nondistributable-artifacts"] = marshalAttributeSlice(newCfg.ServiceOptions.AllowNondistributableArtifacts)
252247
attributes["insecure-registries"] = marshalAttributeSlice(newCfg.ServiceOptions.InsecureRegistries)
253248
attributes["registry-mirrors"] = marshalAttributeSlice(newCfg.ServiceOptions.Mirrors)
254249

daemon/reload_test.go

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package daemon // import "github.com/docker/docker/daemon"
22

33
import (
44
"os"
5-
"sort"
65
"testing"
76

87
"github.com/containerd/log"
@@ -11,7 +10,6 @@ import (
1110
"github.com/docker/docker/libnetwork"
1211
"github.com/docker/docker/registry"
1312
"gotest.tools/v3/assert"
14-
is "gotest.tools/v3/assert/cmp"
1513
)
1614

1715
// muteLogs suppresses logs that are generated during the test
@@ -62,61 +60,6 @@ func TestDaemonReloadLabels(t *testing.T) {
6260
}
6361
}
6462

65-
func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) {
66-
daemon := newDaemonForReloadT(t, &config.Config{})
67-
muteLogs(t)
68-
69-
var err error
70-
// Initialize daemon with some registries.
71-
daemon.registryService, err = registry.NewService(registry.ServiceOptions{
72-
AllowNondistributableArtifacts: []string{
73-
"127.0.0.0/8",
74-
"10.10.1.11:5000",
75-
"10.10.1.22:5000", // This will be removed during reload.
76-
"docker1.com",
77-
"docker2.com", // This will be removed during reload.
78-
},
79-
})
80-
if err != nil {
81-
t.Fatal(err)
82-
}
83-
84-
registries := []string{
85-
"::1/128",
86-
"127.0.0.0/8",
87-
"10.10.1.11:5000",
88-
"10.10.1.33:5000", // This will be added during reload.
89-
"docker1.com",
90-
"docker3.com", // This will be added during reload.
91-
}
92-
93-
newConfig := &config.Config{
94-
CommonConfig: config.CommonConfig{
95-
ServiceOptions: registry.ServiceOptions{
96-
AllowNondistributableArtifacts: registries,
97-
},
98-
ValuesSet: map[string]interface{}{
99-
"allow-nondistributable-artifacts": registries,
100-
},
101-
},
102-
}
103-
104-
if err := daemon.Reload(newConfig); err != nil {
105-
t.Fatal(err)
106-
}
107-
108-
var actual []string
109-
serviceConfig := daemon.registryService.ServiceConfig()
110-
for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs {
111-
actual = append(actual, value.String())
112-
}
113-
actual = append(actual, serviceConfig.AllowNondistributableArtifactsHostnames...)
114-
115-
sort.Strings(registries)
116-
sort.Strings(actual)
117-
assert.Check(t, is.DeepEqual(registries, actual))
118-
}
119-
12063
func TestDaemonReloadMirrors(t *testing.T) {
12164
daemon := &Daemon{
12265
imageService: images.NewImageService(images.ImageServiceConfig{}),

docs/api/version-history.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ keywords: "API, Docker, rcli, REST, documentation"
1717

1818
[Docker Engine API v1.48](https://docs.docker.com/reference/api/engine/version/v1.48/) documentation
1919

20+
# Deprecated: The "allow-nondistributable-artifacts" daemon configuration is
21+
deprecated and enabled by default. The `AllowNondistributableArtifactsCIDRs`
22+
and `AllowNondistributableArtifactsHostnames` fields in the `RegistryConfig`
23+
struct in the `GET /info` response will now always be `null` and will be
24+
omitted in API v1.49.
2025
* `GET /images/{name}/history` now supports a `platform` parameter (JSON
2126
encoded OCI Platform type) that allows to specify a platform to show the
2227
history of.

0 commit comments

Comments
 (0)