Remove panic in nat package on invalid hostport

Closes #14621

This one grew to be much more than I expected so here's the story... :-)
- when a bad port string (e.g. xxx80) is passed into container.create()
  via the API it wasn't being checked until we tried to start the container.
- While starting the container we trid to parse 'xxx80' in nat.Int()
  and would panic on the strconv.ParseUint().  We should (almost) never panic.
- In trying to remove the panic I decided to make it so that we, instead,
  checked the string during the NewPort() constructor.  This means that
  I had to change all casts from 'string' to 'Port' to use NewPort() instead.
  Which is a good thing anyway, people shouldn't assume they know the
  internal format of types like that, in general.
- This meant I had to go and add error checks on all calls to NewPort().
  To avoid changing the testcases too much I create newPortNoError() **JUST**
  for the testcase uses where we know the port string is ok.
- After all of that I then went back and added a check during container.create()
  to check the port string so we'll report the error as soon as we get the
  data.
- If, somehow, the bad string does get into the metadata we will generate
  an error during container.start() but I can't test for that because
  the container.create() catches it now.  But I did add a testcase for that.

Signed-off-by: Doug Davis <dug@us.ibm.com>
Upstream-commit: 12b6083c8f82db7e5db4c683cfe20151731ea851
Component: engine
This commit is contained in:
Doug Davis
2015-07-17 13:02:54 -07:00
parent 4689740e7d
commit a9efb7a3af
11 changed files with 128 additions and 37 deletions
+5 -1
View File
@@ -48,7 +48,11 @@ func (cli *DockerCli) CmdPort(args ...string) error {
proto = parts[1]
}
natPort := port + "/" + proto
if frontends, exists := c.NetworkSettings.Ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
newP, err := nat.NewPort(proto, port)
if err != nil {
return err
}
if frontends, exists := c.NetworkSettings.Ports[newP]; exists && frontends != nil {
for _, frontend := range frontends {
fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort)
}