Commit 380ded6 restored a now-unused endpoint count to the
store, so that when the daemon is downgraded it exists for
the old code to find.
But, on network deletion, the endpoint count was not loaded
from the store - so the delete code saw the wrong "index",
and logged a warning before deleting it anyway.
Use DeleteObject instead of DeleteObjectAtomic, so the old
index isn't checked.
Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 94bcf89412)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
integration/internal/network/ops.go:137:1: ST1020: comment on exported function WithIPAMRange should be of the form "WithIPAMRange ..." (staticcheck)
// WithIPAM adds an IPAM with the specified Subnet, IPRange and Gateway to the network
^
libnetwork/bitmap/sequence.go:50:1: ST1020: comment on exported function New should be of the form "New ..." (staticcheck)
// NewHandle returns a new Bitmap of ordinals in the interval [0, n).
^
libnetwork/diagnostic/server.go:61:1: ST1020: comment on exported method HandleFunc should be of the form "HandleFunc ..." (staticcheck)
// Handle registers the handler function for the given pattern,
^
libnetwork/endpoint.go:388:1: ST1020: comment on exported method Key should be of the form "Key ..." (staticcheck)
// endpoint Key structure : endpoint/network-id/endpoint-id
^
libnetwork/network.go:574:1: ST1020: comment on exported method MarshalJSON should be of the form "MarshalJSON ..." (staticcheck)
// TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
^
libnetwork/network.go:633:1: ST1020: comment on exported method UnmarshalJSON should be of the form "UnmarshalJSON ..." (staticcheck)
// TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/network.go:637:6: shadow: declaration of "v" shadows declaration at line 634 (govet)
if v, ok := n.generic[netlabel.GenericData]; ok {
^
libnetwork/service_linux.go:125:7: shadow: declaration of "ep" shadows declaration at line 86 (govet)
if ep := sb.getGatewayEndpoint(); ep != nil {
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Go maintainers started to unconditionally update the minimum go version
for golang.org/x/ dependencies to go1.23, which means that we'll no longer
be able to support any version below that when updating those dependencies;
> all: upgrade go directive to at least 1.23.0 [generated]
>
> By now Go 1.24.0 has been released, and Go 1.22 is no longer supported
> per the Go Release Policy (https://go.dev/doc/devel/release#policy).
>
> For golang/go#69095.
This updates our minimum version to go1.23, as we won't be able to maintain
compatibility with older versions because of the above.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Since commit 51d7f95 ("libnet: remove struct endpointCnt") an
endpoint count for networks has not been persisted.
But, on downgrade to a version older than that commit, the
missing field caused daemon startup to fail.
So, create the count in the store - it only needs to exist, it's
no longer maintained as a count of endpoints. On downgrade, the
count is probably zero anyway (the daemon is stopped), but the
older daemon fixes it up on startup if necessary.
Signed-off-by: Rob Murray <rob.murray@docker.com>
There have been numerous reports of the "has active endpoints" error
over the years. Historically, there were some faulty code paths that
could lead to this error, but we believe they all have been fixed by
now.
However, users are still facing this error from time to time. Either
because they forgot that some containers are still running, or because
we still have bugs lying around.
To help users figure whether this error is legitimate, and what triggers
it, add endpoint names (which are just container names) to the error
message.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
endpointCnt is a refcounter used to track how many endpoints use a
network, and how many networks references a config-only network. It's
stored separately from the network.
This is only used to determine if a network can be removed.
This commit removes the `endpointCnt` struct and all its references. The
refcounter is replaced by two lookups in the newly introduced `networks`
and `endpoints` caches added to the `Controller`.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The `Controller`'s store is used by:
- `deleteFromStore`
- `getNetworks`
- `getNetworksFromStore`
- `updateToStore`
- … and other methods that can't store / delete / retrieve a Network
Calls to `updateToStore` and `deleteFromStore` have been replaced with
`upsertNetwork` and `deleteNetwork`.
Both `getNetworks` and `getNetworksFromStore` call `cacheNetwork` to
ensure networks loaded from the datastore are kept in-memory.
Finally, `sandboxRestore` was instantiating `Network` itself. These are
cached too.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The `Controller`'s store is used by:
- `deleteFromStore`
- `getEndpointFromStore`
- `getEndpointsFromStore`
- `updateToStore`
- … and other methods that can't store / delete / retrieve an Endpoint
Calls to `updateToStore` and `deleteFromStore` have been replaced with
`upsertEndpoint` and `deleteEndpoint`.
Both `getEndpointFromStore` and `getEndpointsFromStore` call
`cacheEndpoint` to ensure endpoints loaded from the datastore are kept
in-memory.
Finally, `sandboxRestore` was instantiating `Endpoint` itself. These are
cached too.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Creating a swarm network from a config-only network failed
because the new EnableIPv4 wasn't validated/propagated
correctly.
So:
- Always initialise EnableIPv4 to true, including for a config
only network, and on load from the store.
- Treat enableIPv4=true as the no-overridden state when checking
params for a config-from network.
- Propagate settings from the config 'Network' objects attributes
to its generic options, because the network driver only sees
generic options.
- This was happening already for Network.internal, after the
config-only network options were processed. Move that to
'applyConfigurationTo'.
- Add enableIPv4/enableIpv6 - enableIPv6 will normaly be present
anyway. But, for a network created pre-28.x and restored from
the store, there was no entry for 'netlabel.EnableIpv4'.
- Extend TestSwarmScopedNetFromConfig to start a service and
check it's ok.
Signed-off-by: Rob Murray <rob.murray@docker.com>
These need revisiting, similar to similar code in libnetwork/drivers/bridge.
There was already a TODO in place for this, so ignoring these for now.
libnetwork/endpoint.go:148:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
ib, _ := json.Marshal(epMap["ep_iface"])
^
libnetwork/endpoint.go:151:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
jb, _ := json.Marshal(epMap["joinInfo"])
^
libnetwork/endpoint.go:154:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
tb, _ := json.Marshal(epMap["exposed_ports"])
^
libnetwork/endpoint.go:159:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
cb, _ := json.Marshal(epMap["sandbox"])
^
libnetwork/endpoint.go:237:12: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
sal, _ := json.Marshal(epMap["svcAliases"])
^
libnetwork/endpoint.go:242:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
pc, _ := json.Marshal(epMap["ingressPorts"])
^
libnetwork/endpoint.go:247:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
ma, _ := json.Marshal(epMap["myAliases"])
^
libnetwork/endpoint.go:252:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
dn, _ := json.Marshal(epMap["dnsNames"])
^
libnetwork/endpoint_info.go:123:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
rb, _ := json.Marshal(epMap["routes"])
^
libnetwork/endpoint_info.go:490:12: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
tb, _ := json.Marshal(v)
^
libnetwork/network.go:161:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
b, _ := json.Marshal(v)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It was only returned in a few places, and not used any different than
a "invalid parameter" error, so let's use a standard errdefs.ErrInvalidParameter
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It was only returned in 1 place, and not used any different than
a "notfound" error, so let's use a standard errdefs.ErrNotFound
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
commit 80c44b4b2e removed uses of this
method and added a comment that it should never be used;
> EndpointByID should *never* be called as it's going to create a 2nd instance
> of an Endpoint. The first one lives in the Sandbox the endpoint is attached to.
> Instead, the endpoint should be retrieved by calling [Sandbox.Endpoints()].
Given that the only use of this method is in tests, we can remove if altogether.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It was only returned in 2 places, and not used any different than
a "notfound" error, so let's use a standard errdefs.NotFound
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Now a gratuitous/unsolicted ARP is sent, there's no need to
use an IPv4-based MAC address to preserve arp-cache mappings
between an endpoint's IP addresses and its MAC addresses.
Because a random MAC address is used for the default bridge,
it no longer makes sense to derive container IPv6 addresses
from the MAC address. This "postIPv6" behaviour was needed
before IPv6 addresses could be configured, but not now. So,
IPv6 addresses will now be IPAM-allocated on the default
bridge network, just as they are for user-defined bridges.
Signed-off-by: Rob Murray <rob.murray@docker.com>
The default is to send 3 messages at 1s intervals.
That can be overridden in "docker network create" using:
-o com.docker.network.advertise_addr_nmsgs=3
-o com.docker.network.advertise_addr_ms=1000
Or, in daemon.json for each driver:
"default-network-opts": {
"bridge": {
"com.docker.network.advertise_addr_nmsgs": "3",
"com.docker.network.advertise_addr_ms": "1000"
}
}
The allowed range is 0-3 for the number of messages, and
100-2000ms for the interval. Setting nmsgs to 0 disables the
gratuitous ARP/NA messages.
The default bridge will always use the built-in defaults,
it cannot be configured.
Signed-off-by: Rob Murray <rob.murray@docker.com>
A gateway address is always reserved before the network driver is
asked to create the network. But, the driver doesn't always need a
gateway address, so the address reservation can be unnecessary.
This means, for example, an "--internal" IPv4 "/31" network cannot
be used as a point-to-point link, because one of its two addresses
is always reserved for a gateway.
So, before allocating a gateway address, ask the network driver if
it will need one (based on options that only the network driver can
interpret). Implement that as an optional interface for network
drivers.
Signed-off-by: Rob Murray <rob.murray@docker.com>
When setting up a gateway in IpamInfo, and reserving that address in
IPAM ... the IPAM driver may return its own default gateway. That
gateway address is currently always parsed, but it's only used if the
user did not supply their own gateway address. If the user supplied
an address, it's always reserved and used. Otherwise, the IPAM driver
is asked to select and reserve an address.
The logic to deal with that was a bit confusing - and it's probably
better just to ignore the IPAM driver's gateway if it's not going to
be used.
So, simplify it little.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Delete the entries that were added, rather than looking at the service
map (DNS config) and trying to delete entries without accounting for
the container's --hostname.
Signed-off-by: Rob Murray <rob.murray@docker.com>
commit a0807e7cfe configured golangci-lint
to use go1.23 semantics, which alowed linters like `copyloopvar` to lint
using thee correct semantics.
go1.22 now creates a copy of variables when assigned in a loop; make sure we
don't have files that may downgrade semantics to go1.21 in case that also means
disabling that feature; https://go.dev/ref/spec#Go_1.22
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also, libnetwork: Sandbox.buildHostsFile: rename var that shadowed type
Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Rob Murray <rob.murray@docker.com>
Interface DNSBackend.ResolveName, implemented by Network,
Sandbox (and noopDNSBackend) had a bool return value that
meant 'ipv6Miss'.
But, it was always set to true on a hit, and callers had
to deal with that.
So, changed the meaning of the return value to indicate
whether the name was found - which will also work for
'ipv4Miss' when we have IPv6-only containers/networks.
Signed-off-by: Rob Murray <rob.murray@docker.com>
When a container doesn't support IPv6 and it's joined to an IPv6
network, don't allocate an IPv6 address for it.
Update the DNS resolver to understand that it can have an 'ipv6miss'
(meaning an IPv4 address exists, but no IPv6) when a network is
IPv6 enabled.
Signed-off-by: Rob Murray <rob.murray@docker.com>
The new Network.enableIPv4 flag needs to be set for IPv4
networks created before it was introduced.
Commit 903daa4 attempted to do that in the unmarshalling code
by checking Network.ipamV4Info - but, that field hadn't been
unmarshalled yet, so it was never present.
Instead, check for its presence in the saved map.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Also, return IPv6 records from Network.getSvcRecords()
so that /etc/hosts entries are deleted when an IPv6-only
endpoint is removed.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Similar to EnableIPv6:
- Set it if EnableIPv4 is specified in a create request.
- Otherwise, set it if included in `default-network-opts`.
- Apart from in a config-from network, so that it doesn't look
like the API request set the field.
- Include the new field in Network marshalling/unmarshalling test.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Commit 4b9dc647 (from 2016) added this in response to a
review comment, but I don't think it can ever have worked
because n.enableIPv6 = netMap["enableIPv6"].(bool), added
in 2015, would already have panic'd if the field wasn't
stored.
In any case, it's no longer needed.
Signed-off-by: Rob Murray <rob.murray@docker.com>