mirror of https://github.com/containers/podman.git
Ensure the generated NodePort values are unique
... at least within a single service. [NO NEW TESTS NEEDED] because testing RNGs is problematic. (We _could_ probably inject a mock RNG implementation that always returns the same value, or something like that.) Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
parent
a948ecbb9c
commit
f415b30552
|
@ -278,11 +278,13 @@ type servicePortState struct {
|
||||||
// A program using the shared math/rand state with the default seed will produce the same sequence of pseudo-random numbers
|
// A program using the shared math/rand state with the default seed will produce the same sequence of pseudo-random numbers
|
||||||
// for each execution. Use a private RNG state not to interfere with other users.
|
// for each execution. Use a private RNG state not to interfere with other users.
|
||||||
rng *rand.Rand
|
rng *rand.Rand
|
||||||
|
usedPorts map[int]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServicePortState() servicePortState {
|
func newServicePortState() servicePortState {
|
||||||
return servicePortState{
|
return servicePortState{
|
||||||
rng: rand.New(rand.NewSource(time.Now().UnixNano())),
|
rng: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||||
|
usedPorts: map[int]struct{}{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,8 +293,20 @@ func newServicePortState() servicePortState {
|
||||||
func (state *servicePortState) containerPortsToServicePorts(containerPorts []v1.ContainerPort) ([]v1.ServicePort, error) {
|
func (state *servicePortState) containerPortsToServicePorts(containerPorts []v1.ContainerPort) ([]v1.ServicePort, error) {
|
||||||
sps := make([]v1.ServicePort, 0, len(containerPorts))
|
sps := make([]v1.ServicePort, 0, len(containerPorts))
|
||||||
for _, cp := range containerPorts {
|
for _, cp := range containerPorts {
|
||||||
|
var nodePort int
|
||||||
|
attempt := 0
|
||||||
|
for {
|
||||||
// Legal nodeport range is 30000-32767
|
// Legal nodeport range is 30000-32767
|
||||||
nodePort := 30000 + state.rng.Intn(32767-30000+1)
|
nodePort = 30000 + state.rng.Intn(32767-30000+1)
|
||||||
|
if _, found := state.usedPorts[nodePort]; !found {
|
||||||
|
state.usedPorts[nodePort] = struct{}{}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
attempt++
|
||||||
|
if attempt >= 100 {
|
||||||
|
return nil, fmt.Errorf("too many attempts trying to generate a unique NodePort number")
|
||||||
|
}
|
||||||
|
}
|
||||||
servicePort := v1.ServicePort{
|
servicePort := v1.ServicePort{
|
||||||
Protocol: cp.Protocol,
|
Protocol: cp.Protocol,
|
||||||
Port: cp.ContainerPort,
|
Port: cp.ContainerPort,
|
||||||
|
|
Loading…
Reference in New Issue