aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/create.go43
-rw-r--r--test/e2e/run_networking_test.go14
2 files changed, 46 insertions, 11 deletions
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 856fbfa83..54a542ee5 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -371,26 +371,47 @@ func exposedPorts(c *cli.Context, imageExposedPorts map[string]struct{}) (map[na
if err != nil {
return nil, err
}
- l, err := net.Listen("tcp", ":0")
+ rp, err := getRandomPort()
if err != nil {
- return nil, errors.Wrapf(err, "unable to get free port")
- }
- defer l.Close()
- _, randomPort, err := net.SplitHostPort(l.Addr().String())
- if err != nil {
- return nil, errors.Wrapf(err, "unable to determine free port")
+ return nil, err
}
- rp, err := strconv.Atoi(randomPort)
+ logrus.Debug(fmt.Sprintf("Using random host port %d with container port %d", rp, p.Int()))
+ portBindings[p] = CreatePortBinding(rp, "")
+ }
+ }
+
+ // We need to see if any host ports are not populated and if so, we need to assign a
+ // random port to them.
+ for k, pb := range portBindings {
+ if pb[0].HostPort == "" {
+ hostPort, err := getRandomPort()
if err != nil {
- return nil, errors.Wrapf(err, "unable to convert random port to int")
+ return nil, err
}
- logrus.Debug(fmt.Sprintf("Using random host port %s with container port %d", randomPort, p.Int()))
- portBindings[p] = CreatePortBinding(rp, "")
+ logrus.Debug(fmt.Sprintf("Using random host port %d with container port %s", hostPort, k.Port()))
+ pb[0].HostPort = strconv.Itoa(hostPort)
}
}
return portBindings, nil
}
+func getRandomPort() (int, error) {
+ l, err := net.Listen("tcp", ":0")
+ if err != nil {
+ return 0, errors.Wrapf(err, "unable to get free port")
+ }
+ defer l.Close()
+ _, randomPort, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ return 0, errors.Wrapf(err, "unable to determine free port")
+ }
+ rp, err := strconv.Atoi(randomPort)
+ if err != nil {
+ return 0, errors.Wrapf(err, "unable to convert random port to int")
+ }
+ return rp, nil
+}
+
// Parses CLI options related to container creation into a config which can be
// parsed into an OCI runtime spec
func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*createConfig, error) {
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index b56b11634..9a2858ca1 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -77,4 +77,18 @@ var _ = Describe("Podman rmi", func() {
Expect(results.ExitCode()).To(Equal(0))
Expect(results.OutputToString()).To(ContainSubstring(": 80,"))
})
+
+ It("podman run network expose duplicate host port results in error", func() {
+ session := podmanTest.Podman([]string{"run", "-dt", "-p", "80", ALPINE, "/bin/sh"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", "-l"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+
+ containerConfig := inspect.InspectContainerToJSON()
+ Expect(containerConfig[0].NetworkSettings.Ports[0].HostPort).ToNot(Equal("80"))
+ })
+
})