libnetwork: Endpoint: return early if no agent was found

This removes redundant nil-checks in Endpoint.deleteServiceInfoFromCluster
and Endpoint.addServiceInfoToCluster.

These functions return early if the network is not ["cluster eligible"][1],
and the function used for that (`Network.isClusterEligible`) requires the
[agent to not be `nil`][2].

This check moved around a few times ([3][3], [4][4]), but was originally
added in [libnetwork 1570][5] which, among others, tried to avoid a nil-pointer
exception reported in [moby 28712][6], which accessed the `Controller.agent`
[without locking][7]. That issue was addressed by adding locks, adding a
`Controller.getAgent` accessor, and updating deleteServiceInfoFromCluster
to use a local var. It also sprinkled this `nil` check to be on the safe
side, but as `Network.isClusterEligible` already checks for the agent
to not be `nil`, this should not be redundant.

[1]: 5b53ddfcdd/libnetwork/agent.go (L529-L534)
[2]: 5b53ddfcdd/libnetwork/agent.go (L688-L696)
[3]: f2307265c7
[4]: 6426d1e66f
[5]: 8dcf9960aa
[6]: https://github.com/moby/moby/issues/28712
[7]: 75fd88ba89/vendor/github.com/docker/libnetwork/agent.go (L452)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-08-27 11:15:42 +02:00
parent 6eeef51c6a
commit 6203e3660d
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C

View file

@ -618,6 +618,14 @@ func (ep *Endpoint) addServiceInfoToCluster(sb *Sandbox) error {
if !n.isClusterEligible() {
return nil
}
c := n.getController()
agent := c.getAgent()
if agent == nil {
// this should not happen normally, as the network is not considered
// "ClusterEligible" if the agent is nil (in which case we wouldn't
// reach this code).
return nil
}
sb.service.Lock()
defer sb.service.Unlock()
@ -639,9 +647,6 @@ func (ep *Endpoint) addServiceInfoToCluster(sb *Sandbox) error {
return nil
}
c := n.getController()
agent := c.getAgent()
name := ep.Name()
if ep.isAnonymous() {
name = ep.MyAliases()[0]
@ -679,11 +684,9 @@ func (ep *Endpoint) addServiceInfoToCluster(sb *Sandbox) error {
return err
}
if agent != nil {
if err := agent.networkDB.CreateEntry(libnetworkEPTable, n.ID(), ep.ID(), buf); err != nil {
log.G(context.TODO()).Warnf("addServiceInfoToCluster NetworkDB CreateEntry failed for %s %s err:%s", ep.id, n.id, err)
return err
}
if err := agent.networkDB.CreateEntry(libnetworkEPTable, n.ID(), ep.ID(), buf); err != nil {
log.G(context.TODO()).Warnf("addServiceInfoToCluster NetworkDB CreateEntry failed for %s %s err:%s", ep.id, n.id, err)
return err
}
log.G(context.TODO()).Debugf("addServiceInfoToCluster END for %s %s", ep.svcName, ep.ID())
@ -700,6 +703,14 @@ func (ep *Endpoint) deleteServiceInfoFromCluster(sb *Sandbox, fullRemove bool, m
if !n.isClusterEligible() {
return nil
}
c := n.getController()
agent := c.getAgent()
if agent == nil {
// this should not happen normally, as the network is not considered
// "ClusterEligible" if the agent is nil (in which case we wouldn't
// reach this code).
return nil
}
sb.service.Lock()
defer sb.service.Unlock()
@ -714,23 +725,18 @@ func (ep *Endpoint) deleteServiceInfoFromCluster(sb *Sandbox, fullRemove bool, m
return nil
}
c := n.getController()
agent := c.getAgent()
name := ep.Name()
if ep.isAnonymous() {
name = ep.MyAliases()[0]
}
if agent != nil {
// First update the networkDB then locally
if fullRemove {
if err := agent.networkDB.DeleteEntry(libnetworkEPTable, n.ID(), ep.ID()); err != nil {
log.G(context.TODO()).Warnf("deleteServiceInfoFromCluster NetworkDB DeleteEntry failed for %s %s err:%s", ep.id, n.id, err)
}
} else {
disableServiceInNetworkDB(agent, n, ep)
// First update the networkDB then locally
if fullRemove {
if err := agent.networkDB.DeleteEntry(libnetworkEPTable, n.ID(), ep.ID()); err != nil {
log.G(context.TODO()).Warnf("deleteServiceInfoFromCluster NetworkDB DeleteEntry failed for %s %s err:%s", ep.id, n.id, err)
}
} else {
disableServiceInNetworkDB(agent, n, ep)
}
if ep.Iface() != nil && ep.Iface().Address() != nil {