mirror of https://github.com/docker/cli.git
Merge pull request #1102 from sfluor/1074-fix-mapping-a-range-of-host-ports-to-a-single-container-port
Fix mapping a range of host ports to a single container port
This commit is contained in:
commit
2634562119
|
@ -370,9 +370,24 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err
|
||||||
entrypoint = []string{""}
|
entrypoint = []string{""}
|
||||||
}
|
}
|
||||||
|
|
||||||
ports, portBindings, err := nat.ParsePortSpecs(copts.publish.GetAll())
|
publishOpts := copts.publish.GetAll()
|
||||||
|
var ports map[nat.Port]struct{}
|
||||||
|
var portBindings map[nat.Port][]nat.PortBinding
|
||||||
|
|
||||||
|
ports, portBindings, err = nat.ParsePortSpecs(publishOpts)
|
||||||
|
|
||||||
|
// If simple port parsing fails try to parse as long format
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
publishOpts, err = parsePortOpts(publishOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ports, portBindings, err = nat.ParsePortSpecs(publishOpts)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge in exposed ports to the map of published ports
|
// Merge in exposed ports to the map of published ports
|
||||||
|
@ -661,6 +676,23 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parsePortOpts(publishOpts []string) ([]string, error) {
|
||||||
|
optsList := []string{}
|
||||||
|
for _, publish := range publishOpts {
|
||||||
|
params := map[string]string{"protocol": "tcp"}
|
||||||
|
for _, param := range strings.Split(publish, ",") {
|
||||||
|
opt := strings.Split(param, "=")
|
||||||
|
if len(opt) < 2 {
|
||||||
|
return optsList, errors.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
params[opt[0]] = opt[1]
|
||||||
|
}
|
||||||
|
optsList = append(optsList, fmt.Sprintf("%s:%s/%s", params["target"], params["published"], params["protocol"]))
|
||||||
|
}
|
||||||
|
return optsList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
|
func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
|
||||||
loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)
|
loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)
|
||||||
if loggingDriver == "none" && len(loggingOpts) > 0 {
|
if loggingDriver == "none" && len(loggingOpts) > 0 {
|
||||||
|
|
21
opts/port.go
21
opts/port.go
|
@ -151,17 +151,22 @@ func ConvertPortToPortConfig(
|
||||||
if binding.HostIP != "" && binding.HostIP != "0.0.0.0" {
|
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)
|
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)
|
|
||||||
|
startHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort)
|
||||||
|
|
||||||
if err != nil && binding.HostPort != "" {
|
if err != nil && binding.HostPort != "" {
|
||||||
return nil, fmt.Errorf("invalid hostport binding (%s) for port (%s)", binding.HostPort, port.Port())
|
return nil, fmt.Errorf("invalid hostport binding (%s) for port (%s)", binding.HostPort, port.Port())
|
||||||
}
|
}
|
||||||
ports = append(ports, swarm.PortConfig{
|
|
||||||
//TODO Name: ?
|
for i := startHostPort; i <= endHostPort; i++ {
|
||||||
Protocol: swarm.PortConfigProtocol(strings.ToLower(port.Proto())),
|
ports = append(ports, swarm.PortConfig{
|
||||||
TargetPort: uint32(port.Int()),
|
//TODO Name: ?
|
||||||
PublishedPort: uint32(hostPort),
|
Protocol: swarm.PortConfigProtocol(strings.ToLower(port.Proto())),
|
||||||
PublishMode: swarm.PortConfigPublishModeIngress,
|
TargetPort: uint32(port.Int()),
|
||||||
})
|
PublishedPort: uint32(i),
|
||||||
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ports, nil
|
return ports, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,40 @@ func TestPortOptValidSimpleSyntax(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: "80-82:8080/udp",
|
||||||
|
expected: []swarm.PortConfig{
|
||||||
|
{
|
||||||
|
Protocol: "udp",
|
||||||
|
TargetPort: 8080,
|
||||||
|
PublishedPort: 80,
|
||||||
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Protocol: "udp",
|
||||||
|
TargetPort: 8080,
|
||||||
|
PublishedPort: 81,
|
||||||
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Protocol: "udp",
|
||||||
|
TargetPort: 8080,
|
||||||
|
PublishedPort: 82,
|
||||||
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "80-80:8080/tcp",
|
||||||
|
expected: []swarm.PortConfig{
|
||||||
|
{
|
||||||
|
Protocol: "tcp",
|
||||||
|
TargetPort: 8080,
|
||||||
|
PublishedPort: 80,
|
||||||
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
var port PortOpt
|
var port PortOpt
|
||||||
|
|
Loading…
Reference in New Issue