libnetwork/portallocator: assorted cleanups#48373
Conversation
20c88d4 to
12f54ea
Compare
| Begin: start, | ||
| End: end, | ||
| ipMap: ipMapping{}, | ||
| defaultIP: net.IPv4zero, |
There was a problem hiding this comment.
I don't see why it'd be better to turn defaultIP into a PortAllocator property. However, I agree that tests shouldn't rely on this var, and I think we can just ditch that defaultIP altogether ⬇️
There was a problem hiding this comment.
I'm not really tied to this; I initially kept it as a package variable, but decided to move it internal to the PortAllocator, mostly because that's already a singleton and to make it more clear it's internal to that instance, but also (slightly) considering if this would be something configurable (i.e. when instancing the allocator).
| @@ -114,7 +115,7 @@ func (p *PortAllocator) RequestPort(ip net.IP, proto string, port int) (int, err | |||
| // default IP (0.0.0.0). | |||
| func (p *PortAllocator) RequestPortInRange(ip net.IP, proto string, portStart, portEnd int) (int, error) { | |||
There was a problem hiding this comment.
Excluding tests, RequestPortInRange is only called by RequestPort. RequestPort is only called from allocateDaemonPort in a loop that already prevents ip to be nil.
I think we can just drop that defaulting behavior from this method, but it's probably worth taking a defensive stance by returning an error if ip is nil.
There was a problem hiding this comment.
I think I had a patch stashed that removed that loop, which I left out of this PR for now, but, yes, also agreed that we could look at reducing the signature, and remove what we don't need.
|
|
||
| if ip == nil { | ||
| ip = defaultIP | ||
| ip = p.defaultIP // FIXME(thaJeztah): consider making this a required argument and producing an error instead, or set default when constructing. |
There was a problem hiding this comment.
For this one, there's a bit more code involved but I think we're all good too (ie. we can remove this defaulting).
ReleasePorts is called from two places:
attemptBindHostPorts, in a defer while iterating on theaddrsslice, which is built fromportBindingReq.childHostIP. This field is set insetChildHostIP. This method either re-use PBsHostIPas-is (they already get a default value applied), or uses what theportDriverClient.ChildHostIP()returns (which is anetip.Addr).
moby/libnetwork/drivers/bridge/port_mapping_linux.go
Lines 373 to 386 in 609c698
moby/libnetwork/drivers/bridge/port_mapping_linux.go
Lines 400 to 421 in 609c698
moby/libnetwork/drivers/bridge/port_mapping_linux.go
Lines 424 to 432 in 609c698
releasePortBindings, which is called:
a. in a defer inaddPortMappingswith the result ofbindHostPorts() -> attemptBindHostPorts().
b. fromreleasePortswith the list of port mappings that were effectively created.
Maybe it's worth changing the signature of ReleasePorts to make sure no nil net.IP get passed.
I think in the future we should also consider replacing net.IP with netip.Addr.
There was a problem hiding this comment.
Yup; I'd be +1 for sure to make it a hard failure. I was on the fence changing it already, but went looking where the value came from, and there were quite some places where it could be set, so I decided to (for now) leave a TODO here and to leave it for a follow-up.
(Also because I didn't want to shove such a change in a general "cleanup").
|
With the recent changes made by @robmry to our portmapper, I really wonder how useful this whole Maybe we should just ditch this package altogether? WDYT @robmry? |
I think it's still useful to track where to start the search for the next free port (to avoid reallocating the same port for short-lived mappings) - but it could be an internal bridge driver package, and possibly simplified. |
The doc-link was not formatted correctly and didn't work. While updating also slightly touch-up the description to explain "defaultIP". Signed-off-by: Sebastiaan van Stijn <[email protected]>
Signed-off-by: Sebastiaan van Stijn <[email protected]>
Test the functionality in isolation instead of using the singleton that's returned by the `GET` function; this makes sure tests don't affect each other, and doesn't require resetting the singleton in between tests, potentially allowing these tests to eb run in parallel. Signed-off-by: Sebastiaan van Stijn <[email protected]>
Use the variable that's provided by the net package, and make the defaultIP a property of the allocator instead of a package variable. Signed-off-by: Sebastiaan van Stijn <[email protected]>
RequestPortInRange is a wrapper for RequestPortsInRange; skip it as intermediate function. Signed-off-by: Sebastiaan van Stijn <[email protected]>
It was a method on PortAllocator, but not really related, other than reading the default values. Signed-off-by: Sebastiaan van Stijn <[email protected]>
RequestPortsInRange calls portMap.getPortRange() in a loop, but the given port-range is always the same. Perform validation once instead of for each iteration. Signed-off-by: Sebastiaan van Stijn <[email protected]>
These values are configured when instantiating the allocator, and not intended to be mutated externally. They're only used internally with the exception of a test in the bridge driver that uses it to pick a port that can be used for testing. This patch: - un-exports the Begin and End fields - introduces a GetPortRange() utility to allow the bridge driver to get the port, but marking it as a function for internal use. Signed-off-by: Sebastiaan van Stijn <[email protected]>
12f54ea to
8e580ef
Compare
portallocator: RequestPortInRange: fix doc-link in godoc
The doc-link was not formatted correctly and didn't work. While updating
also slightly touch-up the description to explain "defaultIP".
portallocator: ReleaseAll: remove unused error-return
portallocator: use new instance in tests
Test the functionality in isolation instead of using the singleton that's
returned by the
GETfunction; this makes sure tests don't affect each other,and doesn't require resetting the singleton in between tests, potentially
allowing these tests to eb run in parallel.
portallocator: use net.IPv4zero for defaultIP, and make it a property
Use the variable that's provided by the net package, and make the defaultIP
a property of the allocator instead of a package variable.
portallocator: RequestPort: skip RequestPortInRange as intermediate
RequestPortInRange is a wrapper for RequestPortsInRange; skip it as
intermediate function.
portallocator: make newPortMap a regular constructor
It was a method on PortAllocator, but not really related, other than
reading the default values.
portallocator: RequestPortsInRange: validate range once
RequestPortsInRange calls portMap.getPortRange() in a loop, but the given
port-range is always the same. Perform validation once instead of for each
iteration.
portallocator: un-export PortAllocator.Begin, PortAllocator.End
These values are configured when instantiating the allocator, and not
intended to be mutated externally. They're only used internally with
the exception of a test in the bridge driver that uses it to pick a
port that can be used for testing.
This patch:
to get the port, but marking it as a function for internal use.
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)