Skip to content

Validation for mapping a range of host-ports to a single container-port fails #1074

@thaJeztah

Description

@thaJeztah

When running containers, it is both possible to publish a range of host/container ports using the shorthand startport-endport notation:

docker container run -d -p 8080-8081:80-81 --name multi nginx:alpine
fd9b13ed2a03270445812d9349831f936edc55342a9cc7209fc2ab57b0f37974

It's also possible to map multiple host-ports to a single container port:

docker container run -d -p 8080-8081:80 --name multi nginx:alpine
8e289ce242e51934156cd6a2cf088bbf7d3ae645a42208feb5447fbb77526e0f

Mapping a range of host ports to a range of container ports works for services:

docker service create --name multi -p 8080-8081:80-81 nginx:alpine

9q6g4m30qqh5vw4ruffgn16px
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 

However, trying to map a range of hosts-ports to a single container port fails in validation:

docker service create --name multi -p 8080-8081:80 nginx:alpine

invalid argument "8080-8090:80" for "-p, --publish" flag: invalid hostport binding (8080-8090) for port (80)
See 'docker service create --help'.

The last example should work

Error looks to be generated in this function;

cli/opts/port.go

Lines 143 to 167 in 99bd7ed

// ConvertPortToPortConfig converts ports to the swarm type
func ConvertPortToPortConfig(
port nat.Port,
portBindings map[nat.Port][]nat.PortBinding,
) ([]swarm.PortConfig, error) {
ports := []swarm.PortConfig{}
for _, binding := range portBindings[port] {
if binding.HostIP != "" && binding.HostIP != "0.0.0.0" {
logrus.Warnf("ignoring IP-address (%s:%s:%s) service will listen on '0.0.0.0'", binding.HostIP, binding.HostPort, port)
}
hostPort, err := strconv.ParseUint(binding.HostPort, 10, 16)
if err != nil && binding.HostPort != "" {
return nil, fmt.Errorf("invalid hostport binding (%s) for port (%s)", binding.HostPort, port.Port())
}
ports = append(ports, swarm.PortConfig{
//TODO Name: ?
Protocol: swarm.PortConfigProtocol(strings.ToLower(port.Proto())),
TargetPort: uint32(port.Int()),
PublishedPort: uint32(hostPort),
PublishMode: swarm.PortConfigPublishModeIngress,
})
}
return ports, nil
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions