libnet: remove Endpoint.anonymous

No more concept of "anonymous endpoints". The equivalent is now an
endpoint with no DNSNames set.

Some of the code removed by this commit was mutating user-supplied
endpoint's Aliases to add container's short ID to that list. In order to
preserve backward compatibility for the ContainerInspect endpoint, this
commit also takes care of adding that short ID (and the container
hostname) to `EndpointSettings.Aliases` before returning the response.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This commit is contained in:
Albin Kerouanton 2023-11-29 23:02:56 +01:00
parent 7a9b680a9c
commit 6a2542dacf
No known key found for this signature in database
GPG key ID: 630B8E1DCBDB1864
8 changed files with 29 additions and 23 deletions

View file

@ -15,6 +15,8 @@ import (
"github.com/docker/docker/daemon/config" "github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/network" "github.com/docker/docker/daemon/network"
"github.com/docker/docker/errdefs" "github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/sliceutil"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
) )
@ -27,6 +29,18 @@ func (daemon *Daemon) ContainerInspect(ctx context.Context, name string, size bo
return daemon.containerInspectPre120(ctx, name) return daemon.containerInspectPre120(ctx, name)
case versions.Equal(version, "1.20"): case versions.Equal(version, "1.20"):
return daemon.containerInspect120(name) return daemon.containerInspect120(name)
case versions.LessThan(version, "1.45"):
ctr, err := daemon.ContainerInspectCurrent(ctx, name, size)
if err != nil {
return nil, err
}
shortCID := stringid.TruncateID(ctr.ID)
for _, ep := range ctr.NetworkSettings.Networks {
ep.Aliases = sliceutil.Dedup(append(ep.Aliases, shortCID, ctr.Config.Hostname))
}
return ctr, nil
default: default:
return daemon.ContainerInspectCurrent(ctx, name, size) return daemon.ContainerInspectCurrent(ctx, name, size)
} }

View file

@ -70,6 +70,11 @@ keywords: "API, Docker, rcli, REST, documentation"
* `GET /info` now includes `status` properties in `Runtimes`. * `GET /info` now includes `status` properties in `Runtimes`.
* A new field named `DNSNames` and containing all non-fully qualified DNS names * A new field named `DNSNames` and containing all non-fully qualified DNS names
a container takes on a specific network has been added to `GET /containers/{name:.*}/json`. a container takes on a specific network has been added to `GET /containers/{name:.*}/json`.
* The `Aliases` field returned in calls to `GET /containers/{name:.*}/json` in v1.44 and older
versions contains the short container ID. This will change in the next API version, v1.45.
Starting with that API version, this specific value will be removed from the `Aliases` field
such that this field will reflect exactly the values originally submitted to the
`POST /containers/create` endpoint. The newly introduced `DNSNames` should now be used instead.
## v1.43 API changes ## v1.43 API changes

View file

@ -13,7 +13,8 @@ source hack/make/.integration-test-helpers
# --deselect=tests/integration/api_container_test.py::AttachContainerTest::test_attach_no_stream # --deselect=tests/integration/api_container_test.py::AttachContainerTest::test_attach_no_stream
# TODO re-enable test_attach_no_stream after https://github.com/docker/docker-py/issues/2513 is resolved # TODO re-enable test_attach_no_stream after https://github.com/docker/docker-py/issues/2513 is resolved
# TODO re-enable test_run_container_reading_socket_ws. It's reported in https://github.com/docker/docker-py/issues/1478, and we're getting that error in our tests. # TODO re-enable test_run_container_reading_socket_ws. It's reported in https://github.com/docker/docker-py/issues/1478, and we're getting that error in our tests.
: "${PY_TEST_OPTIONS:=--junitxml=${DEST}/junit-report.xml --deselect=tests/integration/api_container_test.py::AttachContainerTest::test_attach_no_stream --deselect=tests/integration/api_container_test.py::AttachContainerTest::test_run_container_reading_socket_ws}" # TODO re-enable test_run_with_networking_config once this issue is fixed: https://github.com/moby/moby/pull/46853#issuecomment-1864679942.
: "${PY_TEST_OPTIONS:=--junitxml=${DEST}/junit-report.xml --deselect=tests/integration/api_container_test.py::AttachContainerTest::test_attach_no_stream --deselect=tests/integration/api_container_test.py::AttachContainerTest::test_run_container_reading_socket_ws --deselect=tests/integration/models_containers_test.py::ContainerCollectionTest::test_run_with_networking_config}"
# build --squash is not supported with containerd integration. # build --squash is not supported with containerd integration.
if [ -n "$TEST_INTEGRATION_USE_SNAPSHOTTER" ]; then if [ -n "$TEST_INTEGRATION_USE_SNAPSHOTTER" ]; then

View file

@ -5,6 +5,7 @@ import (
containertypes "github.com/docker/docker/api/types/container" containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/container"
net "github.com/docker/docker/integration/internal/network" net "github.com/docker/docker/integration/internal/network"
"github.com/docker/docker/integration/internal/swarm" "github.com/docker/docker/integration/internal/swarm"
@ -13,13 +14,13 @@ import (
"gotest.tools/v3/skip" "gotest.tools/v3/skip"
) )
func TestDockerNetworkConnectAlias(t *testing.T) { func TestDockerNetworkConnectAliasPreV144(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType == "windows") skip.If(t, testEnv.DaemonInfo.OSType == "windows")
ctx := setupTest(t) ctx := setupTest(t)
d := swarm.NewSwarm(ctx, t, testEnv) d := swarm.NewSwarm(ctx, t, testEnv)
defer d.Stop(t) defer d.Stop(t)
client := d.NewClientT(t) client := d.NewClientT(t, client.WithVersion("1.43"))
defer client.Close() defer client.Close()
name := t.Name() + "test-alias" name := t.Name() + "test-alias"

View file

@ -47,7 +47,7 @@ func (sb *Sandbox) setupDefaultGW() error {
} }
} }
createOptions := []EndpointOption{CreateOptionAnonymous()} createOptions := []EndpointOption{}
var gwName string var gwName string
if len(sb.containerID) <= gwEPlen { if len(sb.containerID) <= gwEPlen {

View file

@ -31,7 +31,6 @@ type Endpoint struct {
joinInfo *endpointJoinInfo joinInfo *endpointJoinInfo
sandboxID string sandboxID string
exposedPorts []types.TransportPort exposedPorts []types.TransportPort
anonymous bool
// dnsNames holds all the non-fully qualified DNS names associated to this endpoint. Order matters: first entry // dnsNames holds all the non-fully qualified DNS names associated to this endpoint. Order matters: first entry
// will be used for the PTR records associated to the endpoint's IPv4 and IPv6 addresses. // will be used for the PTR records associated to the endpoint's IPv4 and IPv6 addresses.
dnsNames []string dnsNames []string
@ -67,7 +66,6 @@ func (ep *Endpoint) MarshalJSON() ([]byte, error) {
epMap["generic"] = ep.generic epMap["generic"] = ep.generic
} }
epMap["sandbox"] = ep.sandboxID epMap["sandbox"] = ep.sandboxID
epMap["anonymous"] = ep.anonymous
epMap["dnsNames"] = ep.dnsNames epMap["dnsNames"] = ep.dnsNames
epMap["disableResolution"] = ep.disableResolution epMap["disableResolution"] = ep.disableResolution
epMap["svcName"] = ep.svcName epMap["svcName"] = ep.svcName
@ -159,8 +157,9 @@ func (ep *Endpoint) UnmarshalJSON(b []byte) (err error) {
} }
} }
var anonymous bool
if v, ok := epMap["anonymous"]; ok { if v, ok := epMap["anonymous"]; ok {
ep.anonymous = v.(bool) anonymous = v.(bool)
} }
if v, ok := epMap["disableResolution"]; ok { if v, ok := epMap["disableResolution"]; ok {
ep.disableResolution = v.(bool) ep.disableResolution = v.(bool)
@ -206,7 +205,7 @@ func (ep *Endpoint) UnmarshalJSON(b []byte) (err error) {
if !hasDNSNames { if !hasDNSNames {
// The field dnsNames was introduced in v25.0. If we don't have it, the on-disk state was written by an older // The field dnsNames was introduced in v25.0. If we don't have it, the on-disk state was written by an older
// daemon, thus we need to populate dnsNames based off of myAliases and anonymous values. // daemon, thus we need to populate dnsNames based off of myAliases and anonymous values.
if !ep.anonymous { if !anonymous {
myAliases = append([]string{ep.name}, myAliases...) myAliases = append([]string{ep.name}, myAliases...)
} }
ep.dnsNames = sliceutil.Dedup(myAliases) ep.dnsNames = sliceutil.Dedup(myAliases)
@ -229,7 +228,6 @@ func (ep *Endpoint) CopyTo(o datastore.KVObject) error {
dstEp.sandboxID = ep.sandboxID dstEp.sandboxID = ep.sandboxID
dstEp.dbIndex = ep.dbIndex dstEp.dbIndex = ep.dbIndex
dstEp.dbExists = ep.dbExists dstEp.dbExists = ep.dbExists
dstEp.anonymous = ep.anonymous
dstEp.disableResolution = ep.disableResolution dstEp.disableResolution = ep.disableResolution
dstEp.svcName = ep.svcName dstEp.svcName = ep.svcName
dstEp.svcID = ep.svcID dstEp.svcID = ep.svcID
@ -949,14 +947,6 @@ func CreateOptionDNS(dns []string) EndpointOption {
} }
} }
// CreateOptionAnonymous function returns an option setter for setting
// this endpoint as anonymous
func CreateOptionAnonymous() EndpointOption {
return func(ep *Endpoint) {
ep.anonymous = true
}
}
// CreateOptionDNSNames specifies the list of (non fully qualified) DNS names associated to an endpoint. These will be // CreateOptionDNSNames specifies the list of (non fully qualified) DNS names associated to an endpoint. These will be
// used to populate the embedded DNS server. Order matters: first name will be used to generate PTR records. // used to populate the embedded DNS server. Order matters: first name will be used to generate PTR records.
func CreateOptionDNSNames(names []string) EndpointOption { func CreateOptionDNSNames(names []string) EndpointOption {

View file

@ -192,7 +192,6 @@ func TestEndpointMarshalling(t *testing.T) {
name: "Bau", name: "Bau",
id: "efghijklmno", id: "efghijklmno",
sandboxID: "ambarabaciccicocco", sandboxID: "ambarabaciccicocco",
anonymous: true,
iface: &EndpointInterface{ iface: &EndpointInterface{
mac: []byte{11, 12, 13, 14, 15, 16}, mac: []byte{11, 12, 13, 14, 15, 16},
addr: &net.IPNet{ addr: &net.IPNet{
@ -220,7 +219,7 @@ func TestEndpointMarshalling(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if e.name != ee.name || e.id != ee.id || e.sandboxID != ee.sandboxID || !reflect.DeepEqual(e.dnsNames, ee.dnsNames) || !compareEndpointInterface(e.iface, ee.iface) || e.anonymous != ee.anonymous { if e.name != ee.name || e.id != ee.id || e.sandboxID != ee.sandboxID || !reflect.DeepEqual(e.dnsNames, ee.dnsNames) || !compareEndpointInterface(e.iface, ee.iface) {
t.Fatalf("JSON marsh/unmarsh failed.\nOriginal:\n%#v\nDecoded:\n%#v\nOriginal iface: %#v\nDecodediface:\n%#v", e, ee, e.iface, ee.iface) t.Fatalf("JSON marsh/unmarsh failed.\nOriginal:\n%#v\nDecoded:\n%#v\nOriginal iface: %#v\nDecodediface:\n%#v", e, ee, e.iface, ee.iface)
} }
} }

View file

@ -2162,10 +2162,6 @@ func (n *Network) createLoadBalancerSandbox() (retErr error) {
CreateOptionIpam(n.loadBalancerIP, nil, nil, nil), CreateOptionIpam(n.loadBalancerIP, nil, nil, nil),
CreateOptionLoadBalancer(), CreateOptionLoadBalancer(),
} }
if n.hasLoadBalancerEndpoint() && !n.ingress {
// Mark LB endpoints as anonymous so they don't show up in DNS
epOptions = append(epOptions, CreateOptionAnonymous())
}
ep, err := n.createEndpoint(endpointName, epOptions...) ep, err := n.createEndpoint(endpointName, epOptions...)
if err != nil { if err != nil {
return err return err