Merge pull request #2251 from thaJeztah/1962-fix-port-bug

Convert ports before parsing.
This commit is contained in:
Silvin Lubecki 2020-01-16 11:26:44 +01:00 committed by GitHub
commit 0ab564b1c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 31 deletions

View File

@ -379,34 +379,32 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
}
publishOpts := copts.publish.GetAll()
var ports map[nat.Port]struct{}
var portBindings map[nat.Port][]nat.PortBinding
var (
ports map[nat.Port]struct{}
portBindings map[nat.Port][]nat.PortBinding
convertedOpts []string
)
ports, portBindings, err = nat.ParsePortSpecs(publishOpts)
// If simple port parsing fails try to parse as long format
if err != nil {
publishOpts, err = parsePortOpts(publishOpts)
convertedOpts, err = convertToStandardNotation(publishOpts)
if err != nil {
return nil, err
}
ports, portBindings, err = nat.ParsePortSpecs(publishOpts)
ports, portBindings, err = nat.ParsePortSpecs(convertedOpts)
if err != nil {
return nil, err
}
}
// Merge in exposed ports to the map of published ports
for _, e := range copts.expose.GetAll() {
if strings.Contains(e, ":") {
return nil, errors.Errorf("invalid port format for --expose: %s", e)
}
//support two formats for expose, original format <portnum>/[<proto>] or <startport-endport>/[<proto>]
// support two formats for expose, original format <portnum>/[<proto>]
// or <startport-endport>/[<proto>]
proto, port := nat.SplitProtoPort(e)
//parse the start and end port and create a sequence of ports to expose
//if expose a port, the start and end port are the same
// parse the start and end port and create a sequence of ports to expose
// if expose a port, the start and end port are the same
start, end, err := nat.ParsePortRange(port)
if err != nil {
return nil, errors.Errorf("invalid range format for --expose: %s, error: %s", e, err)
@ -796,9 +794,10 @@ func parseNetworkAttachmentOpt(ep opts.NetworkAttachmentOpts) (*networktypes.End
return epConfig, nil
}
func parsePortOpts(publishOpts []string) ([]string, error) {
func convertToStandardNotation(ports []string) ([]string, error) {
optsList := []string{}
for _, publish := range publishOpts {
for _, publish := range ports {
if strings.Contains(publish, "=") {
params := map[string]string{"protocol": "tcp"}
for _, param := range strings.Split(publish, ",") {
opt := strings.Split(param, "=")
@ -809,6 +808,9 @@ func parsePortOpts(publishOpts []string) ([]string, error) {
params[opt[0]] = opt[1]
}
optsList = append(optsList, fmt.Sprintf("%s:%s/%s", params["published"], params["target"], params["protocol"]))
} else {
optsList = append(optsList, publish)
}
}
return optsList, nil
}

View File

@ -873,8 +873,33 @@ func TestParseSystemPaths(t *testing.T) {
}
}
func TestParsePortOpts(t *testing.T) {
parsed, err := parsePortOpts([]string{"published=1500,target=200", "target=80,published=90"})
func TestConvertToStandardNotation(t *testing.T) {
valid := map[string][]string{
"20:10/tcp": {"target=10,published=20"},
"40:30": {"40:30"},
"20:20 80:4444": {"20:20", "80:4444"},
"1500:2500/tcp 1400:1300": {"target=2500,published=1500", "1400:1300"},
"1500:200/tcp 90:80/tcp": {"published=1500,target=200", "target=80,published=90"},
}
invalid := [][]string{
{"published=1500,target:444"},
{"published=1500,444"},
{"published=1500,target,444"},
}
for key, ports := range valid {
convertedPorts, err := convertToStandardNotation(ports)
if err != nil {
assert.NilError(t, err)
assert.DeepEqual(t, []string{"1500:200/tcp", "90:80/tcp"}, parsed)
}
assert.DeepEqual(t, strings.Split(key, " "), convertedPorts)
}
for _, ports := range invalid {
if _, err := convertToStandardNotation(ports); err == nil {
t.Fatalf("ConvertToStandardNotation(`%q`) should have failed conversion", ports)
}
}
}